众所周知,HTTP/1.0是HTTP协议的首个完整版本,它在协议中描述了我们常用的一些概念,例如首部(Header)、响应码(Status Code)、重定向(Redirect)、更多的方法(Post、Put、Delete等)。
而到了HTTP/1.1又带来了众多新的概念,例如缓存首部、OPTIONS方法、Upgrade首部、Range请求、管道化(Pipelining)、压缩和传输编码(transfer-encoing)。
然而随着Web越来越复杂,访问一个页面需要获取的资源越来越多,HTTP/1的一些缺陷也带来了性能上的问题。这里列举了几个比较重要的问题。
队头阻塞(Head-of-line blocking,或缩写为HOL blocking)
当我们的网站需要获取多份资源时(例如多张图片),HTTP/1协议下,如果只使用一个连接,则需要完成发起请求、等待响应这一对操作后,才可以发起下一次请求。在获取响应的过程中,一旦发生了任何问题,剩余的所有请求都会被阻塞住,此时页面也将无法渲染导致最终失去响应。
为了解决这种问题,浏览器一般都会开启多个连接来并发请求,然而每个连接依旧会受到“队头阻塞“的影响。
低效的TCP
我们知道TCP是一种可靠性非常高的通信协议,它通过滑动窗口和拥塞控制,保证了即使在最差的网络下数据也能的可靠的传输。其中有个非常重要的概念叫“慢启动”,它是用来探索当前连接对应拥塞窗口的大小,目的是用来让新的连接了解当前网络状况,避免给已经拥堵的网络继续添堵。
注:拥塞窗口指的是,在接收方确认接收到数据包前,发送方可以发送的包的数量。
然而这种方式虽然让网络避免了拥堵,却让通信的效率非常的低下。多次的数据往返才能确认最佳拥塞窗口,而且实际的实现中,遇到丢包的情况,拥塞算法通常会选择缩小拥塞窗口。甚至遇到超时时,甚至会重置拥塞窗口导致重新进入慢启动阶段。
首部臃肿
HTTP/1请求的首部是无法进行压缩的,现如今Web页面中加入的首部越来越多,大小也越来越多,无法压缩的首部也势必给通信效率带来不良的影响。
正因为HTTP/1存在的众多问题,社区上出现了很多针对性的优化,例如优化DNS查询、缓存机制、代码压缩、避免CSS/JS阻塞等。如果能从协议上去解决这些问题,才是问题最好的解决方式。
HTTP/2的协议基础来源于Google提出的SPDY协议,SPDY提出的多路复用、帧和首部压缩这些功能,也被最终整合进了HTTP/2协议中。
HTTP/2包含如下几种特性: