HTTP协议的进化——HTTP/2
据W3Techs统计,截至2017年11月,排在前1千万名的网站中有20.5%的支持HTTP/2。Chrome、Opera、Firefox、Internet Explorer 11、Safari、Amazon Silk和Edge浏览器都支持HTTP/2的标准化。大多数主流浏览器都在2015年底之前添加了HTTP/2支持。
HTTP/2对HTTP/1.x进行了大量简化,使得性能得到了大幅度提升。Akamai公司官网通过一个示例对比了HTTP/1.1和HTTP/2在性能上的差距——并发请求379张图片,HTTP/1.1需要14.70s,响应时间为3ms,而HTTP/2仅仅需要1.61s,响应时间为6ms,如图2-21所示。
我们都知道,在HTTP/1.x的协议中,浏览器在同一时间对同一域名下的请求数量是有限制的,这会导致大量并发请求阻塞,这个问题也被称为线端阻塞(head-of-line blocking)。同一域名下浏览器支持的连接数,如表2-4所示。HTTP/1.1对不同浏览器连接数的限制不同,很多互联网公司为了解决这个问题,做了大量优化,包括建立多域名,通过CDN缓存大量静态资源等。
HTTP/2是基于二进制协议的,与HTTP/1.x这样的文本协议相比,显然二进制协议性能更高。另外HTTP/2使用报头压缩,降低了网络开销。HTTP/2将HTTP协议通信分解为二进制编码帧的交换,这些帧对应着特定数据流中的消息。所有这些消息都在一个TCP连接内复用,这就是HTTP/2的多路复用机制(Multiplexing)。Benjamin在2015年写的一篇文章中描述了一个简单的例子,如果只请求3个资源,从Web页面开始渲染到加载结束,HTTP/2比HTTP/1.1节省不少时间,如图2-22所示。
图2-22 HTTP/1.1和HTTP/2调用流程对比
HTTP/2完全兼容HTTP/1.1的语义,HTTP/2和HTTP/1.1的大部分高级语法(例如方法、状态码、头字段和URI)都是相同的。
HTTP/1.1如果要实现长连接,需要设置Connection:keep-alive来控制长连接时间,超时就断开TCP连接。只有在客户端发起请求的时候,服务器端才会响应。所以就算一直给服务器发送心跳包以维持长连接,也不能用来推送,只有客户端不断发起请求给服务器端,服务器才会响应,这就是pull轮询的方式。
HTTP/2引入服务端推送模式,即服务端向客户端发送数据,如图2-23所示。服务器可以对一个客户端请求发送多个响应,HTTP/2打破了严格的请求-响应语义,支持一次请求-多次响应的形式。由于现如今的Web界面丰富多彩,加载的资源往往非常多,服务端实际上已经知道要推送什么内容,但HTTP/1.x的语义只支持客户端发起请求、服务端响应数据。HTTP/2改变了这种模式,只需要客户端发送一次请求,服务端便把所有的资源都推送到客户端。服务器推送的缺点是,在客户端已经缓存了资源的情况下可能会有冗余。这个问题可以通过服务器提示(Server Hint)解决。