只是简单记录下对HTTP2的学习。

1. HTTP1.x

在介绍HTTP2之前,还是要简单回顾下HTTP1/1.x。

当我们打开一个页面的时候,可能会请求很多个其他资源,包括js,css,图片等,在HTTP1.x的模型下,不开启特殊优化的情况下每个请求都会新建一个TCP连接来访问数据。

这就跟多线程模型一样,虽然并行同时处理的更多,不过对资源的消耗也更大,所以一般来说浏览器都会有一个对同一个域名的并发数的限制,一般也就是4~10左右。

有很多优化方案都是用来解决这个问题的,比如常见的keep-alive,keep-alive允许对同一个TCP连接进行复用,避免每个请求都新建TCP连接。

除了并发限制之外,还有一个很大的问题是HTTP1.x协议是不支持对Header进行压缩的,比如我们常用来存储用户session ID的cookies,如果是同一个域名每次请求都会带上,不管有没有必要,对于小一点的网站来说不算什么,对于流量大的网站来说这个带宽消耗也是值得关注的。

同样对于这个也有很多现成的解决方案,比如我们很多时候都会把静态资源单独的放到一个域名下面,这样既可以避免header携带不必要的cookies信息也可以通过不同域名来规避浏览器的并发限制。

2. HTTP2

HTTP2在一定程度上解决了上面的问题,HTTP2的关键词可以总结为下面几点:

  • 二进制传输
  • 多路复用
  • Header压缩
  • Server Push

2.1 二进制传输 & 多路复用

HTTP1.x的所有内容都是采取文本形式传输的,而到了HTTP2的则采用了二进制传输,这样解析起来会比文本更加高效,同时简化了多路复用的实现。

多路复用可以说是HTTP2 vs HTTP1.x 最质变的一个特性了,这个的核心主要就是只使用一个TCP连接来进行并行传输,对传输的数据进行二进制打包,通过stream id来区分不同的请求。

这个特性在一个页面有如几百张图片这种非常多的请求时候效果非常明显,虽然keep-alive这种东西也可以实现单TCP连接传输,但是keep-alive并不是一种并发的传输方式,keep-alive只是简单的对一个TCP连接进行复用,传输方式依然是A->B->C,如果遇见一个特别大的B依然会阻塞C。而stream是单TCP连接进行并发传输,不会出现一个大文件阻塞其他请求的情况。

在HTTP1.x的时候我们有很多优化方式其实就是为了解决连接数过多的问题的,比如css和js打包,把多张图片组合成一张图片通过css来选取位置,使用多个域名来规避并发限制,这些“打包”做法有些时候其实并不是很友好,比如我们一个1mb的js,只改了一行就需要重新缓存整个js,而在http2的协议下我们可以不打包资源文件,这样可以更高效的利用缓存机制。

2.2 Header压缩

HTTP2可以采用hpack对header进行压缩了,hpack不仅仅是简单的对数据进行压缩,同时还会维护一张保存重复信息的hash表,来减少重复信息的发送,诸如user-agent,cookies这种信息都会只发送一次了。

2.3 Server Push

Server Push这个东西的原理大概是这样,比如客户请求了index.html, index.html内会请求style.css,在请求index.html的时候实际上我们就已经知道客户会请求style.css,我们可以在客户发送请求style.css之前就push过去。

这个对各种SPA应用还是很实用的,不过目前还没有很好的最佳实践,具体是否使用可能还有待参考。

简单总结下,http2已经可以投入使用了,很多网站应该已经升级到http2了,不过使用的时候还是要注意一些问题,比如有一些老的浏览器并不支持http2,对于这种浏览器可能还是要打包资源,同时HTTP2基本只应该使用https协议来传输,http协议可能还有些问题。

References: