众所周知,在前端性能优化篇里有一条优化建议:使用雪碧图合并图片资源、合并js请求数,那么为什么会有这么一条优化建议?这是因为在采用http1.1协议下有如下缺点:
1、TCP 连接数限制
对于同一个域名,浏览器最多只能同时创建 6~8 个 TCP 连接 (不同浏览器不一样)。
在HTTP1.1的环境下,在图中可以看到每新建了六个 TCP 连接,每次新建连接 DNS 解析需要时间(几 ms 到几百 ms 不等)、TCP 慢启动也需要时间、TLS 握手又要时间,而且后续请求都要等待队列调度
2、线头阻塞问题
每个 TCP 连接同时只能处理一个请求 - 响应,浏览器按 FIFO 原则处理请求,如果上一个响应没返回,后续请求 - 响应都会受阻。
3、Header 内容多,而且每次请求 Header 不会变化太多,没有相应的压缩传输优化方案
4、为了尽可能减少请求数,需要做合并文件、雪碧图、资源内联等优化工作,但是这无疑造成了单个请求内容变大延迟变高的问题,且内嵌的资源不能有效地使用缓存机制
5、明文传输不安全
那么如何解决这些问题?http2登场:
HTTP2 的优势:
二进制分帧:
在二进制分帧层上,HTTP 2.0 会将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码 ,其中HTTP1.x的首部信息会被封装到Headers帧,而我们的request body则封装到Data帧里面。
多路复用:
代替原来的序列和阻塞机制。HTTP2只需要通过一次TCP连接将并发请求全部发出,而HTTP1.1则每并发一次请求就需要建立一次TCP连接,当前浏览器为了控制资源,会对单个域名有 6-8个的TCP链接请求限制,如果遇到某一个资源加载耗时较久,就会拖累整个站点的加载速度。
头部压缩:
HTTP 2在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对。通过对称加密的方式客户端和服务端之前的通信只需用一个更短的‘’暗号“来匹配之间的需要通信的内容,如果首部发生变化了,那么只需要发送变化了数据在Headers帧里面,新增或修改的首部帧会被追加到“首部表”,首部表在 HTTP 2的连接存续期内始终存在,由客户端和服务器共同渐进地更新 。将大大节省消息头占用的网络的流量
服务器推送:
HTTP1.1的方式,客户端浏览器解析到哪里需要什么资源再加载什么资源,在HTTP2中,服务端可以主动推送,结合业务场景,服务端可以先把关键的首要的资源首先推送给客户端。只需要一次HTTP请求,浏览器就得到了首要资源,页面性能大大提升。
如何使用HTTP2 :
由于目前主流浏览器,chrome、火狐等都已经公开宣布只支持加密的HTTP2,所以HTTP2基本都是基于HTTPS协议的,HTTP升级成HTTPS需要SSL证书,可以到阿里云免费申请,这边以自己的博客nginx配置作为参考
注:升级openssl1.1.x+、 Nginx 1.9.5
server {
#这里配置https和http2协议
listen 443 ssl http2;
server_name blog.reviosky.com;
ssl on;
root /data/blog/admin/dist/;
try_files $uri /index.html;
#下面配置ssl证书路径
ssl_certificate /etc/nginx/conf.d/cert/7218208_blog.reviosky.com.pem;
ssl_certificate_key /etc/nginx/conf.d/cert/7218208_blog.reviosky.com.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
root /data/blog/admin/dist/;
try_files $uri /index.html;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS,PUT,DELETE;
#用于强制取消浏览器缓存
if ($uri ~* "html$") {
add_header 'Cache-Control' 'no-cache';
}
}
location /api/ {
proxy_pass http://127.0.0.1:7001/admin/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
server_name blog.reviosky.com;
rewrite ^(.*)$ https://$host$1 permanent; #把http的域名请求转成https
charset utf-8;
autoindex off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS,PUT,DELETE;
if ($request_method = OPTIONS ) {
return 200;
}
location / {
root /data/blog/admin/dist/;
try_files $uri /index.html;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS,PUT,DELETE;
#用于强制取消浏览器缓存
if ($uri ~* "html$") {
add_header 'Cache-Control' 'no-cache';
}
}
location /api/ {
proxy_pass http://127.0.0.1:7001/admin/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
HTTP1.1升级HTTP2后前后对比:
使用前
使用后
可以看到tcp连接数由多个转变成一个,加载完所有图片的速度得到了提升
666
123
😜