http1.1和http2.0在请求379张图片的对比演示(HTTP2.0性能惊人)。
HTTP2.0是HTTP协议自1999年HTTP1.1发布后的首个更新,主要基于SPDY(读speedy)。 该协议在2015年以RFC 7540正式发表 。
基本介绍
HTTP/1.1 时代
HTTP/1.1 对 HTTP/1.0 做了许多优化,也是当今使用得最多的 HTTP 协议:
- 持久化连接(keep-alive)以支持连接重用
- 分块传输编码(chunked)以支持流式响应
- 请求管道以支持并行请求处理
- 字节服务以支持基于范围的资源请求
- 改进的更好的缓存机制
这里所说的持久链接是指:在HTTP1.0时代,每一个请求都会重新建立一个TCP连接,一旦相应返回,就关闭链接,而建立一个链接,需要进行三次握手,这极大的浪费了性能。而HTTP1.1新增了【keep-alive】功能,当浏览器建立一个TCP链接时,多个请求都会使用这个连接。 (现在大多数浏览器都是默认开启的。)
而我们所说的pipeLining管道是解决另一个问题:在TCP链接中,同一时间内只能够发送一个请求,并且需要等到响应完成之后才能发送第二个请求。因此HTTP/1.1制定了Pipelining管道,通过这个管道,浏览器的多个请求可以同时发送到服务器,但是服务器的响应只能一个接着一个的返回(但是各大浏览器不支持/默认关闭,所以这个功能就是鸡肋了)。
所以,由于鸡肋的功能,最终HTTP/1.1还是一条链接只能返回一个响应,因此浏览器为了改善这种情况,会同时开启4~8个TCP链接进行发送请求。
如何使用上 HTTP/2.0
- 需要浏览器的支持,目前最新版的 Chrome、Opera、 FireFox、 IE11、 edge 都已经支持了
- 需要 WEB 服务器的支持,比如 Nginx , H20
如果浏览器或服务器有一方不支持,那么会自动变成 Http/1.1
HTTP的基本优化
影响一个HTTP网络请求的因素主要有两个:带宽和延迟。
- 带宽:如果说我们还停留在拨号上网的阶段,带宽可能会成为一个比较严重影响请求的问题,但是现在网络基础建设已经使得带宽得到极大的提升,我们不再会担心由带宽而影响网速,那么就只剩下延迟了。
- 延迟:
- 浏览器阻塞(HOL blocking):浏览器会因为一些原因阻塞请求。浏览器对于同一个域名,同时只能有 4 个连接(这个根据浏览器内核不同可能会有所差异),超过浏览器最大连接数限制,后续请求就会被阻塞。
- DNS 查询(DNS Lookup):浏览器需要知道目标服务器的 IP 才能建立连接。将域名解析为 IP 的这个系统就是 DNS。这个通常可以利用DNS缓存结果来达到减少这个时间的目的。
- 建立连接(Initial connection):HTTP 是基于 TCP 协议的,浏览器最快也要在第三次握手时才能捎带 HTTP 请求报文,达到真正的建立连接,但是这些连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。
1、连接和拼接
链接或者拼接JS和CSS文件,雪碧图,以减少HTTP请求,同时浏览器可以缓存这些静态资源,为下次访问节约时间。但是这样带来的副作用是,维护成本高,其中某一个小改动都会使得整个拼接后的文件发生改变,重新缓存。
当然并不是说无止境的拼接,建议大小为: 30~50 KB
2、域名分区
由于浏览器的限制,同一个域下最多只能建立6个连接。我们通常使用子域名来减少所有资源在只有一个连接时的产生的排队延迟。
3、资源内嵌
对于不常用的,较小大资源内嵌在文档中,比如base64的图片,以减少HTTP请求,但是这样的资源不能在浏览器中缓存,也不可能被其他页面共享,同时还有可能编码之后的资源变等更大了。
SPDY 时代
由于现代网页的不断丰富, HTTP/1.1 协议的性能也逐渐吃不消,因此2012年google如一声惊雷提出了SPDY的方案,实际上,HTTP/2.0 也是以 SPDY 作为原型进行开发的。
SPDY基础功能
多路复用(multiplexing)
多路复用通过多个请求stream共享一个tcp连接的方式,解决了http1.x holb(head of line blocking)的问题,降低了延迟同时提高了带宽的利用率。
请求优先级(request prioritization)
多路复用带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY允许给每个request设置优先级,这样重要的请求就会优先得到响应。比如浏览器加载首页,首页的html内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,这样可以保证用户能第一时间看到网页内容。
header压缩
前面提到过几次http1.x的header很多时候都是重复多余的。选择合适的压缩算法可以减小包的大小和数量。SPDY对header的压缩率可以达到80%以上,低带宽环境下效果很大。
SPDY 现已经被大多数浏览器以及 WEB 服务器所支持,但为了推进 HTTP/2.0, Google 已经宣布在 2016年对其停止开发。
HTTP/2.0 时代
二进制分帧
在应用层与传输层之间增加一个二进制分帧层,以此达到“在不改动HTTP的语义,HTTP 方法、状态码、URI及首部字段的情况下,突破HTTP1.1的性能限制,改进传输性能,实现低延迟和高吞吐量。”
在二进制分帧层上,HTTP2.0会将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,其中HTTP1.x的首部信息会被封装到Headers帧,而我们的request body则封装到Data帧里面。
压缩头部
HTTP/2.0规定了在客户端和服务器端会使用并且维护「首部表」来跟踪和存储之前发送的键值对,对于相同的头部,不必再通过请求发送,只需发送一次
事实上,如果请求中不包含首部(例如对同一资源的轮询请求),那么首部开销就是零字节。此时所有首部都自动使用之前请求发送的首部。
如果首部发生变化了,那么只需要发送变化了数据在Headers帧里面,新增或修改的首部帧会被追加到“首部表”。首部表在 HTTP2.0的连接存续期内始终存在,由客户端和服务器共同渐进地更新。
多路复用
HTTP/2.0 时代拥有了「多路复用」功能,意思是: 在一条连接上,我可以同时发起无数个请求,并且响应可以同时返回。(这个难点终于被解决了)
客户端和服务器可以把HTTP消息分解为互不依赖的帧,然后乱序发送,最后再在另一端把它们重新组合起来。注意,同一链接上有多个不同方向的数据流在传输。客户端可以一边乱序发送stream,也可以一边接收者服务器的响应,而服务器那端同理。
注意,对一个域名,只需要开启一条 TCP 连接,请求都在这条 TCP 连接上干活。
因此在 HTTP/2.0 时代,之前的合并 JS、CSS 文件技巧,反而不适用了。
请求优先级
既然所有资源都是并行发送,那么就需要「优先级」的概念了,这样就可以对重要的文件进行先传输,加速页面的渲染。
服务器推送
在 HTTP2.0中,服务器推送是指在客户端请求之前发送数据的机制。如果一个请求是由你的主页发起的,服务器很可能响应主页内容、logo以及样式表,因为它知道客户端会用到这些东西。这相当于在一个 HTML 文档内集合了所有的资源,不过与之相比,服务器推送有一个很大的优势:可以缓存!
强制 SSL
虽然 HTTP/2.0 协议并没声明一定要用 SSL,但是 Google Chrome 等浏览器强制要求使用 HTTP/2.0 必须要用上 SSL, 也就是说必须要: https://
对优化的影响:
- 因为“所有的HTTP2.0的请求都在一个TCP链接上”,“资源合并减少请求”,比如CSS Sprites,多个JS文件、CSS文件合并等手段没有效果,或者说没有必要。
- 因为“多路复用”,采用“cdn1.cn,cdn2.cn,cdn3.cn,打开多个TCP会话,突破浏览器对同一域名的链接数的限制”的手段是没有必要的。因为因为资源都是并行交错发送,且没有限制,不需要额外的多域名并行下载。
- 因为“服务器推送”,内嵌资源的优化手段也变得没有意义了。而且使用服务器推送的资源的方式更加高效,因为客户端还可以缓存起来,甚至可以由不同的页面共享(依旧遵循同源策略)
HTTP2.0与SPDY的区别
SPDY是谷歌公司2012年推出的一个新的协议,而HTTP2.0是基于SPDY的协议,所以HTTP2.0是SPDY的升级版! 所以,两者必然有不同之处。
- 新的二进制形式。 HTTP1.x的解析是基于文本。而基于文本协议的格式解析天然就存在缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景很多 ,即要考虑很多;而二进制形式则不同,只认0和1的组合,所以这种协议解析实现方便而且健壮 。
- 多路复用。 即链接共享,每一个request都是用链接共享机制的, 一个request对应一个id,这样一个连接上可以有多个request, 每个链接的request可以随机的混杂在一起,接收方可以根据request的id将request再归属到不同的服务器请求了。
- header压缩。HTTP2.0通过HPACK进行压缩,这种压缩方法是特意为HTTP2.0设定的。
- 服务器推送。同SPDY一样,HTTP2.0也具有server push功能。
为什么需要头部压缩?
假定一个页面有100个资源需要加载(这个数量对于今天的Web而言还是挺保守的), 而每一次请求都有1kb的消息头(这同样也并不少见,因为Cookie和引用等东西的存在), 则至少需要多消耗100kb来获取这些消息头。HTTP2.0可以维护一个字典,差量更新HTTP头部,大大降低因头部传输产生的流量。
HTTP2.0多路复用有多好?
之前就提到了,http性能取决于带宽和延迟连个方面,现在带宽已经很好了,几乎不再是阻碍,真正的阻碍是延迟! HTTP 性能优化的关键并不在于高带宽,而是低延迟。TCP 连接会随着时间进行自我「调谐」,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度。这种调谐则被称为 TCP 慢启动。由于这种原因,让原本就具有突发性和短时性的 HTTP 连接变的十分低效。HTTP/2 通过让所有数据流共用同一个连接,可以更有效地使用 TCP 连接,让高带宽也能真正的服务于 HTTP 的性能提升。
参考文章: HTTP2.0简单总结 、HTTP1.0/1.1/2.0的区别