常见的前端性能优化手段都有哪些?都有多大收益?

常见的前端性能优化手段都有多大收益?有啥数据可以参考吗? 经常见到各种前端性能优化的方法,比如合并JS、开启Keep Alive之类,但是这些方法到底都有多大收益呢?有哪些数据可以参考?
关注者
781
被浏览
12635

14 个回答

下面讲一下我的测试,基本思想就是测试一种优化手段在使用前后性能是否有所提升,以及提升了多少。我测试的优化手段是以下几个:合并请求、域名拆分、开启Gzip、开启keepalive、Minify。

刚好春节前为了做技术分享做过一组测试,我可以分享一下自己的数据。(一般收益有多大根据业务不同也会不同的,硬要说有多大收益,其实并没有一个“标准”,我的数据也只能做个参考)。

构造被测页面
因为不同的网站页面大小不同,js/css个数不同,图片个数不同,比如淘宝首页和百度首页差别就非常大,所以构造被测页面确实没有一个完美的方法。我采用的方法是参考httparchive(http://httparchive.org/)最近的统计值,决定网页中有多少个js/css和图片,以及它们的大小(数字并没有完全精确相等,但是比较接近),所以,构造的基准网页结构如下:
1.总请求数90,总大小1.6MB
2.HTML请求1个,大小4.1KB
2.CSS请求5个,总大小71.2KB,内容为一些开源的CSS库,因为测试只考虑网页的加载性能,不考虑渲染性能,所以CSS规则冲突之类的问题可以忽略。
3.JS请求27个,总大小404KB,内容为一些开源的JS代码,和上一条原因相同,忽略JS的执行效率问题,选择的代码中不包含对dom树的更改,所以理论上不会影响资源加载进度。
4.图片请求57个,总大小1.1MB,其中大图12张,体积3KB以下的小图标45个。

选择测试工具
这种测试最好有大量的测试样本和精确的指标计算,手工测试会累残,单机测试也不准,最好在全网范围内进行真实用户客户端的测试。市面上有一些提供测试的服务商,选择了其中的性能魔方(http://www.mmtrix.com/),有免费额度可用,收费版也不贵。

构造被测网站
这个不多说了,阿里云上买了一台虚拟机,绑定了域名,开了nginx,对不同的优化手段进行不同的配置,比如开关gzip的配置等。虚拟机是1核2G,Ubuntu的系统,按流量收费,峰值带宽100M。说个题外话,按流量收费真是太贵了,做个测试差点没把我做破产。

优化手段1:合并请求
合并请求的主要目的是减少浏览器对服务器发起的请求数,从而减少在发起请求过程中花费的时间。本测试采用了合并JS、合并CSS以及合并小图片(也就是使用CSS精灵)等方式来减少请求。优化前,页面的请求数和大小如上文所说,优化后,情况如下:
1.总请求数18,总大小1.6MB
2.HTML请求1个,大小4.3KB
2.CSS请求2个,总大小70.5KB,考虑到很多网站会有各个页面都使用的公用CSS,所以测试中并未把所有CSS合并成1个,而是合并成了两个。
3.JS请求2个,总大小398KB,与上一条理由差不多,也合并成了两个JS文件。
4.图片请求13个,总大小1.1MB,使用工具将45个小图标合并成了一张图片。
合并前的网页地址:jianfeng.in/combine/ind,未开Gzip,未开KeepAlive
合并后的网页地址:jianfeng.in/combine/com,未开Gzip,未开KeepAlive
(现在访问这两个地址可能会有点慢,因为我把云主机的配置从100M带宽按流量收费改成了1M带宽按带宽收费了,测试的时候阿里云光流量费用就一天收了我100多大洋,再也不敢这么任性了)
啰嗦了这么多,是时候看结果了

上图中,颜色越靠近绿色速度就越快,越靠近红色就越慢。可以很直观的看出,在全国范围内,未优化网页明显比合并请求的网页慢很多。


可以看出,在2月6日一整天的测试数据中,优化前后所有样本的平均整页时间(总下载时间)从10.65秒提升到了4.15秒,性能提升1.56倍,同时可用性也有所提高,主要是因为请求数变少了,请求出错的概率就降低了。这里可以得出一个结论,在使用HTTP/1.1和HTTP/1.0的时候,能减少HTTP请求就尽量减少HTTP请求,因为每个请求都会消耗很多时间。对于使用HTTP/2.0的情况,我还了解不多,貌似使用Server Push技术可以无视资源数,有高手知道还望指教。

优化手段2:域名拆分
域名拆分主要是为了增加浏览器下载的并行度,让浏览器能同时发起更多的请求,所以本组实验主要由三个实验对象:
1.上文描述的基准网页,地址为:jianfeng.in/combine/ind
2.将基准网页中的JS、CSS和图片分别使用三个域名加载,分别是 js.jianfeng.incss.jianfeng.inimg.jianfeng.in,地址为:jianfeng.in/dns/dns3.ht
3.在2的基础上进行更多的拆分,共9个,分别为js1.jianfeng.injs2.jianfeng.incss1.jianfeng.incss2.jianfeng.inimg1.jianfeng.inimg2.jianfeng.inimg3.jianfeng.inimg4.jianfeng.inimg5.jianfeng.in,地址为:jianfeng.in/dns/dns9.ht
同样都未开启Gzip,未开启KeepAlive,结果如下

从结果中可以看出,拆分域名后,整页加载时间有所减低,但是并没有合并请求效果那么明显。其中,拆分为3个域名之后,整页时间降低了22%,拆分为9个之后,整页时间降低了25%
其实这里有一点不符合我的预期,按照我看到的资料,域名拆分为3到5个比较合适,过多的域名会带来DNS解析时间的损耗,可能会降低性能,所以9个域名应该不会比3个域名性能好。在我的实验里,9个域名的DNS解析总时间也确实最长,达到了0.77秒。个人猜测,原因可能是在我的实验中,请求数比较多,DNS解析带来的性能损耗比并行下载带来的性能提升要小,所以总体上9个域名的性能还是比3格域名要好的。当然,这里只是猜测,大家如果有不同见解,可以评论里讨论。

优化手段3:开启Gzip
Gzip是一种压缩技术,可以将资源在服务端进行压缩,然后发送给浏览器后再进行解压,这种方式会降低传输大小,提高网页加载性能。本组实验的实验对象有两个:
1.基准网页,地址为:jianfeng.in/combine/ind
2.对基准网页开启Gzip,地址为:gzip.jianfeng.in/combin
两个网页均未开启KeepAlive,结果如下:

从结果可以看出,开启Gzip后,整页时间从10.65秒降低到10.06秒,性能提升5.5%,页面大小从1572.14KB降低到1257.69KB,降幅为20%。由于测试页面中大量的内容是图片,而我又只对JS/CSS/HTML类型的资源开启了Gzip,所以优化收益一般,对于以文本为主的页面,Gzip的优化收益应该是很大的。

优化手段4:开启KeepAlive
开启KeepAlive能够减少浏览器与服务器建立连接的次数,从而节省建立连接时间。本组实验的对象有两个:
1.基准网页,地址为:jianfeng.in/combine/ind
2.对基准网页开启了keepalive,地址为:keep.jianfeng.in/combin
两个网页均未开启gzip,结果如下:

从结果可以看出,开启KeepAlive后,整页时间从10.65秒降低到6.19秒,性能提升41.8%,建立连接次数从89次降低到8次,建立连接总时间从7.31秒降低到1.86秒。对于同一个主机上请求数较多的的页面,开启KeepAlive可以较好的提高性能,但是开启KeepAlive也会使服务器负载变大,也更加容易遭受攻击,实际项目中需要权衡利弊。

优化手段5:Minify
Minify指的是将JS和CSS等文本文件进行最小化处理,一般对于CSS来说就是去除空格去除换行去除注释等,对于JS,除了上述方法外,还可以进行变量名替换,将长变量名替换为短变量名。目前有很多用户做Minify的工具,例如uglifyjs等。由于Minify只是对文本类资源进行的优化操作,所以本组实验的两个实验对象都是对基准网页进行一定的处理后而来,首先将基准网页中的图片删去大部分,只保留一张,其次,将JS和CSS先进行合并处理。得到实验对象如下:
1.未做Minify的网页,地址为:jianfeng.in/minify/inde
2.对JS和CSS做了Minify的网页,地址为:jianfeng.in/minify/mini
以上两个网页均未开启gzip和keepalive,结果如下:

从结果可以看出,minify前后,整页时间从1.69秒降低到了1.24秒,性能提升了26.6%,页面大小从504.05KB减小到224.52KB,降幅为55.4%。Minify除了可以提高页面加载速度之外,还有另外一个收益,那就是可以降低网站的带宽费用,因为Minify是实实在在减小网页大小的。

总结
上述几个测试算是可以粗糙的证明常见的网页性能优化手段都是有收益的。在实验里有些手段收益大,有些手段收益小,在实际生产环境中,还是要根据自己的站点实际情况以及投入产出比进行使用。总之,别人的数据对自己的产品的价值还是有限的,重点是测试自己的站点,衡量自己的收益,用自己的数据指导自己的优化行为,这样才能获得更好的用户体验。
除了技术手段优化,还有一点是:

如果遇到不合理或者有问题的地方,直接提出来推动产品或视觉改掉,这部分代码写都不要写。