HTTP/1.x的缺陷
- 连接无法复用,需要开启多个连接
- 没有进行头部压缩,协议开销大
- 线头阻塞
HTTP/2 协议中的一些主要新特性
1. 性能提升的核心——二进制帧层
性能提升的核心在于二进制帧层.它指HTTP消息在客户端和服务端如何封装和传输.采用二进制格式传输数据而非HTTP/1.x的文本传输,二进制格式在解析和优化扩展上具有更多的优势。
2. 多路复用
在HTTP/1.1中,如果客户端为了提高性能想要在一个TCP连接内同时发起多个请求,每个请求必须按顺序被服务器依次响应,如果某一个请求特别耗时,那么后面的请求将会被一直阻塞。
而在HTTP/2中,如果在一个TCP连接内同时发起多个请求,每个消息可以被拆成互不依赖的帧并且各帧之间交错发送,然后在另一端重新把帧组装起来。这个特性就叫做多路复用。
3.头部压缩-HPACK
HTTP 1.1请求的大小变得越来越大,有时甚至会大于TCP窗口的初始大小,因为它们需要等待带着ACK的响应回来以后才能继续被发送。HTTP/2对消息头采用HPACK(专为http2头部设计的压缩格式)进行压缩传输,能够节省消息头占用的网络的流量。而HTTP/1.x每次请求,都会携带大量冗余头信息,浪费了很多带宽资源
4.Server Push
服务端可以在发送页面HTML时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。例如服务端可以主动把JS和CSS文件推送给客户端,而不需要客户端解析HTML再发送这些请求。服务端可以主动推送,客户端也有权利选择接收与否。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送RST_STREAM帧来拒收。主动推送也遵守同源策略,服务器不会随便推送第三方资源给客户端。
在Node.js中配置HTTP/2
使用OpenSSL生成ssl自签名证书
下载及安装OpenSSL
生成私钥
genrsa -des3 -out server.key
生成csr
req -new -key server.key -out server.csr
创建自签名证书
x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Node.js 服务搭建
使用koa2 脚手架初始化项目
npm install -g koa-generator
koa2 -e HTTP2_VS_SPRITE
安装 http2 模块
npm i http2
配置HTTP/1.1 以及 HTTP/2 server
...
var http = require('http');
var http2 = require('http2');
var fs = require('fs');
/**
* Get port from environment and store in Express.
*/
var port = '3000';
var port2 = '3001';
// app.set('port', port);
var options = {
key: fs.readFileSync(process.cwd() + '/ssl/server_no_passwd.key'),
cert: fs.readFileSync(process.cwd() + '/ssl/server.crt')
}
/**
* Create HTTP server.
*/
var server = http.createServer(app.callback());
var h2_server = http2.createSecureServer(options,app.callback())
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
h2_server.listen(port2);
...
图片加载对比
使用图片切割工具,把一张大小为6M的图片平均切分为255份,得到255张小图片。并在页面中通过两个端口请求这些图片
HTTP/1.1:
<img src="http://localhost:3000/images/1.jfif" width="32" height="32" alt="">
<img src="http://localhost:3000/images/2.jfif" width="32" height="32" alt="">
<img src="http://localhost:3000/images/3.jfif" width="32" height="32" alt="">
...
HTTP/2:
<img src="https://localhost:3001/images/1.jfif" width="32" height="32" alt="">
<img src="https://localhost:3001/images/2.jfif" width="32" height="32" alt="">
<img src="https://localhost:3001/images/3.jfif" width="32" height="32" alt="">
...
在Chrome浏览器打开测试页面
为了使结果对比明显,使用Chrome 将拟网络环境模拟为 fast 3G
以下为测试结果:
HTTP/1.1 加载速度
HTTP/2 加载速度
可以看到,由于多路复用的加持,HTTP/2 的加载速度明显更快
在Chrome控制台导出.har文件,并使用在线分析工具:HAR Viewer
得到如下结果:
HTTP/1.1
har_h1.pngHTTP/2.0
har_h2.png可以看到,在极端网络条件下使用HTTP/1.1, 加载时长为26.56s, 而使用HTTP/2, 加载总时长为17.26s, 快了将近40%。
雪碧图
1.原理
CSS Sprites 因其英文被称为雪碧图。
主要用于把一堆小图标整合在一张背景透明的大图上,通过设置对应的位置来显示不同的图片,目的是大幅减轻服务器对图片的请求数量,是前端性能优化的一种方式。
2.优缺点:
- 优点:减少网页的HTTP请求,提高页面性能, 减少图片命名的困扰
- 缺点:需要计算每个图片的位置,且难以维护
3.生成雪碧图
将前面提到的255张切割图制作成雪碧图
在线生成雪碧图:https://www.toptal.com/developers/css/sprite-generator
将生成的css文件以及雪碧图引入到项目中。
在测试页面中修改以背景图的方式加载图片:
<div class="image-grid bg-1"></div>
<div class="image-grid bg-2"></div>
<div class="image-grid bg-3"></div>
...
同样的方式,在浏览器打开测试页面,并将浏览器网路模拟到fast 3G
以下是测试结果
load_sprite.pnghar包分析结果:
har_sprite.png从结果可以看到,由于生成的雪碧图过大,在网络状况不是很好的条件下,加载时间来到了2分钟以上
总结
在以上对比中,由于图片过大而导致请求时间过长,而在实际应用中一般很少存在有如此之大的雪碧图,所以在请求时间上相比于HTTP/2可能没有过大的优势,但是考虑上它的维护成本,在HTTP/2时代雪碧图显然已不再被推荐,HTTP1.1时代,所有为了减少请求而做出的HACK,都已不再是HTTP/2性能优化考虑的主要点了。
目前HTTP/2兼容性:
caniuse.png
其次,由于字体图标的灵活性以及良好的兼容性,使得雪碧图更是毫无优势可言。
网友评论