HTTP1.1的队头阻塞
队头阻塞是指当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,会导致客户端迟迟收不到数据。针对队头阻塞,人们尝试过以下办法来解决:
-
将同一页面的资源分散到不同域名下,提升连接上限。 Chrome有个机制,对于同一个域名,默认允许同时建立 6 个 TCP持久连接,使用持久连接时,虽然能公用一个TCP管道,但是在一个管道中同一时刻只能处理一个请求,在当前的请求没有结束之前,其他的请求只能处于阻塞状态。另外如果在同一个域名下同时有10个请求发生,那么其中4个请求会进入排队等待状态,直至进行中的请求完成。
-
合并小文件减少资源数。精灵图,Spriting合并多张小图为一张大图,再用JavaScript或者CSS将小图重新“切割”出来的技术。
-
内联(Inlining)资源是另外一种防止发送很多小图请求的技巧,将图片的原始数据嵌入在CSS文件里面的URL里,减少网络请求次数。 减少请求数量。拼接(Concatenation)将多个体积较小的JavaScript使用webpack等工具打包成1个体积更大的JavaScript文件,但如果其中1个文件的改动就会导致大量数据被重新下载多个文件。
多路复用
就是请求的都是通过一个 TCP 连接并发完成。因为在多路复用之前所有的传输是基于基础文本的,在多路复用中是基于二进制数据帧的传输、消息、流,所以可以做到乱序的传输。多路复用对同一域名下所有请求都是基于流,所以不存在同域并行的阻塞。
最大并发数问题,
假设我们在 Apache 中设置了最大并发数 300,而因为浏览器本身的限制,最大请求数为 6,那么服务器能承载的最高并发数是 50
而 HTTP/2 引入二进制数据帧和流的概念,其中帧对数据进行顺序标识,这样浏览器收到数据之后,就可以按照序列对数据进行合并,而不会出现合并后数据错乱的情况。同样是因为有了序列,服务器就可以并行的传输数据。
HTTP/2 对同一域名下所有请求都是基于流,也就是说同一域名不管访问多少文件,也只建立一路连接。同样Apache的最大连接数为300,因为有了这个新特性,最大的并发就可以提升到300,比原来提升了6倍