前端性能优化(三)聊聊HTTP/2带来的加载优化
那些年,我们使用HTTP1.1,我们忍受着巨大的网络延时,而同时我们的网页变得越来越复杂,我们需要加载的资源越来越大越来越多。
- 建立HTTP链接,由于HTTP是基于TCP的,所以必然要经过TCP的三次握手。
- 发送请求,TCP有慢启动的问题。
- 接收响应。
- 如果连接被双方认可是keep-alive的,那么后续请求可复用该连接发送请求。
对,这里面有一个问题,就是一个HTTP连接同一时刻只能处理一个资源的请求,处理完才可能处理下一个。
当然HTTP1.1有一个可选的Pipelining技术,说的意思是当一个HTTP连接在等待接收响应时可以通过这个连接发送其他请求。听起来很棒,其实这里有一个坑,处理响应是按照顺序的,也就是后发的请求有可能被先发的阻塞住,也正因此很多浏览器默认是不开启Pipelining的。
- 无法应对越来越多的资源加载数量
- 无法应对越来越大的资源加载体积
- 网络延迟及其严重,Pipelining有让人抓狂的阻塞问题
- 未能榨干TCP的性能
- 过多的可选项带来了严重的互用性问题
- 合并请求。既然延迟严重,那么把多个小的请求合并成一个大的请求,比如Spriting、inline、文件合并。
- Sharding。这个涉及到一个问题,浏览器在同一个域名下允许创建的最大连接数是有一个上限的(一般桌面端6~8个,手机端少一些),如果想建立更多的链接那么将资源分散到不同域名就可以做到了,而且同时带来一个额外的好处是对于一些静态资源可以减少cookie的传输。
- 提升加载速度,降低协议对网络延迟的敏感度
- 降低连接数,连接多也是对资源的浪费
- 解决Pipelining的阻塞问题
- 平滑升级,保留现有的使用方式,这也是我们程序设计中要追求的
- HTTP/2是二进制协议
- 多路复用技术
- 压缩HTTP头
- 服务端推送
- 协议层面提供的传输控制能力,如流量控制、优先级等
需要重点说的是多路复用,前面说过Pipelining技术会有阻塞的问题,HTTP/2的多路复用可以粗略的理解为非阻塞版的Pipelining。即可以同时通过一个HTTP连接发送多个请求,谁先响应就先处理谁,这样就充分的压榨了TCP这个全双工管道的性能。加载性能会是HTTP1.1的几倍,需要加载的资源越多越明显。当然多路复用是建立在加载的资源在同一域名下,不同域名神仙也复用不了。
HTTP头压缩。以前我们的头部信息很小,没有压缩的必要,但是现在我们发送的头信息已经大的惊人了,可以看看现在的cookie。
服务端推送。现在还有些鸡肋,各浏览器实现有差异或者是bug。这个推送并不是我们想的服务器主动推送消息,而是客户端请求A资源的时候服务器可以把除A外的B资源一并推到客户端,这样在需要B的时候B已经在客户端了,节省一次请求和响应时间。服务端推送需要编写代码实现,原因也很简单,毕竟文件间的依赖关系只有写代码的人知道。依赖关系要从工程划角度来解决,生成一个描述依赖关系的文件,程序来读取文件决定推送哪些文件。未来CDN厂商也会支持通过依赖描述文件来让我们完全前后端分离的前端代码能使用服务端推送来提速。关于服务端推送我会另写一篇文章来说明。
HTTP/2普及需要一个时间过程,现在很多CDN厂商已经支持了,比如阿里云CDN。
从图中可以看出,所有浏览器都是只支持基于TLS的HTTP2,非HTTPS或者基于SSL的HTTPS都是不OK的。而且很多浏览器仅支持ALPN这种协商机制,这个机制是客户端提供一个协议支持列表,服务器端从中挑选一个来建立通讯连接。
不当之处欢迎指正,多谢多谢。
小姜哥:前端性能优化(一)用一张图说明加载优化小姜哥:前端性能优化(二)通过一个实例聊聊DOM操作优化