美文网首页
HTTP2,让首屏性能提升30%的一次实践

HTTP2,让首屏性能提升30%的一次实践

作者: 0月 | 来源:发表于2019-08-11 19:49 被阅读0次

前言

公司官网改版后,发现要加载很多图片,这些图片都是一些动画效果需要的,所以导致打开页面的时候,一直有200+的图片请求,如下图红色标记第3点处,页面load耗时3.61s。虽然就体验来说还行,但从技术角度分析来说,我还是想把它做得更好一点;于是我想到了HTTP2,便叫运维同学一起来弄一下。

image.png

HTTP2

什么是HTTP2 ?
比较官方专业的解释可以看这里https://zh.wikipedia.org/wiki/HTTP/2
按照我的理解就是http协议的2.0版本,简称h2。

既然是2.0版本,那么必然有1.0版本,事实上却也是如此,截止到目前2019年,http协议版本就有0.9、1.0、1.1、2.0四个版本。而目前在市面上的网站大多数都是使用1.1和2.0的版本。以下是这些版本之间的一些简介。


HTTP协议版本简介.png

使用h2,必须要满足以下几个条件:
1、网站加了基于TLS的连接的https证书
2、服务器开启h2支持

2015年之后的主流浏览器都默认开启了h2的支持,Internet ExplorerIE 11开始支持HTTP/2,并预设激活。

h2的优点:

1、多路复用
多路复用允许同时通过单一的 h2 连接发起多重的请求-响应消息。在 HTTP/1.1 协议中浏览器在同一时间,同一域名下的请求有一定数量限制,chrome浏览器默认是单域名同时不能超过6个请求。一旦超过限制数目的请求会被阻塞。这也是为何一些站点会有多个静态资源 CDN 域名的原因之一。而 h2 的多路复用(Multiplexing) 则只需要建立一个TCP连接,所有的请求-响应都在这个连接上进行传输,并没有数量的限制,也不用再去分发多个域名去加载静态资源了。

2、帧数据传输
将传输数据分割成二进制帧有什么好处?
在HTTP/1.1在连接中的明文请求中,假如你请求一个html,对应的content-type是“text/html”, 请求一张png图片是“image/png”。对于不同类型的数据在传输过程中都有不同的策略,而http协议要覆盖所有的类型的传输策略这是一件非常耗费资源繁琐的事情,而h2则将每个请求的资源在传输时都统一转换成最原始的二进制帧(Frame),然后在客户端统一转成对应的资源类型。这也是HTTP/1.1与h2最大的区别所在。 协议将每个请求分割为二进制的控制帧与数据帧部分,以便解析,这相比HTTP/1.1,新页面加载可以加快11.81% 到 47.7%。

3、头部压缩
我们知道每个http请求都有请求头,请求头部里面都是一些“key-value”的东西。在一个页面中,如果有很多的请求,而每个请求的请求头里面都是差不多的key-value,那么每次请求的请求头就会传相同的内容,这样子就有点浪费带宽了,在HTTP/1.1中首部是没有压缩的,gzip只会压缩body,h2就提供了首部压缩使得整个HTTP数据包小了很多,传输也就会更快。

怎么压缩的呢?

HPACK算法是新引入h2的一个算法,用于对HTTP头部做压缩,它的原理是在服务器和客户端各维护一个“首部表”,表中用索引代表首部名,或者首部key-value,上一次发送两端都会记住已发送过哪些首部,下一次发送只需要传输差异的数据,相同的数据直接用索引表示即可,另外还可以选择地对首部值压缩后再传输。按照这样的设计,如果多次请求的首部基本是一样的,那之后的请求基本只需要几个索引就可以了。

4、支持服务端推送
服务端推送需要客户端先请求过一次之后才能决定是否推送。
哪些属性设置可以让服务端推送?
h2服务器推送策略:

  • 在自身的代码中明确发起服务器推送
    如preload属性
    <link href="/style.css" rel="preload" as="style" />

  • 通过额外的 HTTP 首部向服务器发送信号,列出希望推送的资源
    在请求头中加个Link的key,对应的value内容是你需要推送的资源,具体例子如下:
    Link: </style.css>; rel=preload; as=style, </example.png>; rel=preload; as=image

  • 可以不依赖应用而自动学习相关资源。服务器可以解析文档,推断出要推送的资源,或者可以分析流量,然后作出适当的决定

什么时候推送?
如果每次请求都推送的话,会存在浪费带宽的现象,最好的方式是第一次请求的时候推送,怎么判断是第一次请求?可以在cookie里面做个标识。而且推送的资源也要慎重考虑,不要请求一个index.html就把这个网站所有的资源都推了,这对服务器和浏览器都有较大的负荷,这样反而会拖累性能。

最后附上开启h2之后的官网的例子:

由于我这边用vue打包的代码里面本身就有了类似这样的代码:
<link href="/static/js/chunk-vendors.17459ce8.js" rel="preload" as="script">
所以我这边基本满足了要求,而服务器是nginx,就需要它开启支持h2的模块了,这里遇到一点小问题就是nginx开启http2模块之后一定要关掉nginx进程然后重启才行。
最后效果如图,load时间是2.34秒

1.PNG

说到底,我这里的优化就是利用到了h2的多路复用的特性。

理论上是会同时并行发200个请求,然后等这些请求响应即可。而之前是200个请求会由于浏览器的同源策略限制,每个源最多并发请求是6个,所以是先并行发6个请求,然后剩下的排队发,在同一时刻只能有6个请求,等到200个请求全部响应的话,时间上耗时比较长!

实际上:
并没有一次性发200个请求,而会根据浏览器与服务器的硬件配置去选择并发几个。即使这样也比http1.1的串行要快。

最后

如有疑问或者错误,欢迎留言指出讨论,谢谢。

相关文章

网友评论

      本文标题:HTTP2,让首屏性能提升30%的一次实践

      本文链接:https://www.haomeiwen.com/subject/vpvllctx.html