Web性能优化之HTTP2
Web作为网络资源的访问入口,延迟其实才是目前性能优化的瓶颈。SPDY协议的开发者之一Mike Belshe在15年时测试了互联网上最热门的一些站点,结果如下 可以看出,带宽达到4Mbps以后,页面的加载时间变化不大,而延迟和页面加载时间完全是成正比关系。
HTTP1.1的瓶颈
HTTP1.1时代里,每次TCP连接只能下载一个资源,比如向服务器请求index.html文件,浏览器拿到index.html文件,解析index.html时遇到<link>
、<script>
等标签时,又会发送请求获取对应的css、js等资源,这就引发两个问题:
1.每请求一个资源就会来一次TCP连接,且有"队首阻塞"问题出现,这样在资源过多的情况下,TCP连接消耗的时间会逐渐增加
2.每次发送请求的HTTP头部信息基本相同,造成头部信息冗长,耗费流量
3.从获取解析index.html文件到碰撞<link>
、<script>
等标签时,中间流失的时间没有充分利用
HTTP2
一句话概述它的优点: 合并请求,并行下载,缩小数据,预先加载
SPDY作为该协议的试验场,HTTP2以它为基础一直在不断地做出变化和改进。
1.二进制分帧层
之所以要递增一个大版本到2.0,主要是因为它新增了二进制分帧层
作为客户端与服务器之间交换数据的新方式。
2.多向请求与响应
在HTTP1.x中,需要使用多个TCP连接才可以让客户端发送多个并行请求,且每个连接只能接受一个响应。HTTP2突破了这些限制,不同于之前使用换行符分隔纯文本的方式,二进制分帧机制以二进制编码格式将HTTP消息分解为互不依赖的帧,然后乱序发送,在另一端把根据每个帧首部的流标识符重新组装。 从图中我们可以看出在这一条连接中客户端在传送stream5,也在接收stream3和stream3,请求之间互不影响,因此解决了HTTP1.x中存在的"队首阻塞"问题,且只用一个连接就可以发送多个请求和响应,避免了多次连接的时间消耗。
3.服务器推送
同时,HTTP2新加入了一个推送功能,就是出了返回最初请求的资源外,服务器还可以推送额外的资源给客户端缓存,避免二次请求。
4.首部压缩
HTTP2通过"首部表"来对跟踪和存储之前发送过的首部键值对,如果数据相同,将只发送差异部分,且首部表在链接保持时会始终存在。
可以看到,在请求#2
里的header帧将只发送差异部分。
使用HTTP2
我们尝试在一个node服务里使用HTTP2
首先新建文件夹,在该目录下创建公私密钥:
> openssl req -new -newkey rsa:2048 -nodes -keyout localhost.key -out localhost.csr
> openssl x509 -req -days 365 -in localhost.csr -signkey localhost.key -out localhost.crt
创建package.json文件:
> npm init -y
再安装HTTP2包:
> npm i --save-dev http2
新建app.js文件
const https = require('http2');
const fs = require('fs');
const options = {
key: fs.readFileSync('localhost.key'),
cert: fs.readFileSync('localhost.crt')
};
https.createServer(options, function (request, response) {
response.writeHead(200);
response.end('welcome to use HTTP2');
}).listen(443);
启动服务:
> node app.js
我使用了chrome 插件 HTTP/2 and SPDY indicator来查看网站是否启用了HTTP2或SPDY
现在访问 https://localhost 可以看到,经过检测,我们的服务已经成功开启了HTTP2