前端重构实践(一) —— 性能优化

  • 前言:

最近一直在作性能优化和模块化改造的工做,并完成了一次前端重构。在这里总结出一些经验和得失来帮助你们思考。共两篇文章,第一篇讨论性能优化,第二篇讨论模块化框架。而之因此把这两个话题放到一块儿,是由于这两项工做都涉及到对前端代码进行不一样程度的重构,并且模块化改造实际上是咱们在对性能优化作到必定程度以后发现必需要作的一件事情。本篇是性能优化的部分,下面我把咱们的产品简称为N页面。php

  • 应用场景分析:

N页面做为一个入口页面,对页面加载速度有着极高的要求。同时,N页面内部却又有着很是复杂的功能与交互。N页面的初版上线时,页面引用的js文件有3个,一共40-50k(压缩&Gzip以后)。页面onload时间在1.3秒。前端

1.3秒的load时间,相比较绝大多数网站来讲都是一个不错的数值。但老板一句话“怎么这个页面打开这么慢”,马上像是给咱们的后背安了一枚×××。性能优化成了N页面下一步工做的重中之重。json

老板重视页面速度,对于Web前端开发人员来讲实际上是件幸事,这代表你将有更丰富的时间和资源去实践Web性能优化这一课题,不用被翻来覆去的产品升级需求所打扰。那么对于N页面,咱们作了哪些实践:浏览器

 

常规优化手段包括缓存

CSS置顶,JS置底。性能优化

静态资源外联、合并、压缩。网络

图片优化。(Png使用pngcrush;Gif使用gifsicle;Jpeg使用jpegtran)框架

图片延迟加载。(主要针对首屏外的图片。)ide

使用CSS Sprite,首屏图片所有合到一张图上。模块化

静态文件上CDN。(静态文件的下载能提速20%左右。)

静态文件设置强缓存。(命中强缓存82.4%;命中若缓存3.4%;未命中缓存14.2%。)

HTML压缩。(Gzip后减小%5。)

加强型手段

基础库定制。(用代码分析代码,自动打包被使用到的方法做为基础库,使基础库从原来的压缩后25K减少为9.8K,减少了61%)

页面数据存储优化。(从原来的直接写json形式的script,变为将json隐藏在textarea中,初始化或用到的时候才去提取并进行解析。)

首屏CSS检测。(对首屏用到的CSS进行检测,将不属于首屏的CSS代码单独打包并移到首屏以外进行延迟加载)

js按需加载。(在后面作重点介绍)

  • 监控& 测量

性能优化最重要的工做不是优化而是监控。这个道理很简单:没有监控体系就没办法衡量性能优化的效果,那么你所作的任何工做都是盲目的。

咱们对性能的监控是从多个维度展开的,包括平均时间、时段分布、浏览器分布、省份、运营商等。便于发现和定位任何一个细节的问题。

而在平均时间这一维度,咱们又分为四个级别:

Head时间– head标签加载完成的时间

TTi时间– 页面可交互时间(即首屏第一次渲染出来的时间)

Dom时间– Dom Ready的时间

Load 时间– 页面彻底加载完成的时间

这样划分的好处是,页面加载每一个环节的耗时一目了然:

Head :CSS加载时间

TTI :总体HTML加载和渲染时间

DOM 减TTI : js文件网络传输时间和在浏览器进行解析的时间

Load 减Dom : js初始化+ 图片加载的时间

并且,咱们经过移动tti时间点的位置,发现了一个有趣的现象,以下图

能够看出,页面加载的性能瓶颈就在script的下载和解析时间。

为了进一步定位性能瓶颈,咱们在页面内对用户网速进行了测试,结果很震惊:有2%的用户网速小于2k/s,5%的用户网速小于10k/s。(国内的网络情况真是惨不忍睹啊)

那么,优化方案就很明显了:最大限度地减少js文件大小,以减少网络传输时间,提高页面性能。

经过后来的优化工做咱们发现:js代码压缩、Gzip后每减少1k,页面加载时间就能减少10ms左右。

  • 按需加载:

这是除了js压缩外,你能想到的最有效减少js文件大小的办法了。

按需加载,顾名思义,就是在页面首次加载的时候只提供最须要的js给用户,而剩余的js等用户使用到了相关的功能再去加载。

按需加载适合哪一种类型的网站:若是80%的用户来到你的页面只使用20%的功能,那么就有必要把这20%的js做为首屏加载,而剩余的js作按需加载。

从这个角度来说,几乎全部网站均可以作按需加载,由于总有一些功能是用户不多会用到的。

那么,如何作按需加载:

按需加载须要有一套js模块加载的框架。这个框架的做用是:保障在所需的js加载完成后才去执行回调方法。

按需加载还须要有一套触发条件。在咱们的页面中,对鼠标移动和鼠标点击都进行了监听,以保障在用户想使用某个功能以前或进行了相应操做时,触发js加载。

除此以外,咱们还对js基础库进行了进一步拆分,分为首屏用到的基础方法,和延迟加载的js所需的基础方法。以最大限度地保证首屏js量的最小化。

经过按需加载的拆分,咱们将首屏的js代码从原来的gzip以后40-50k减少到了只有24k。

同时,咱们对CSS的加载也进行拆分,首屏不须要的CSS代码也随JS进行延迟加载。

  • 效果 & 总结

性能优化是一个很是繁琐的工做,页面性能受不少因素的制约,不过相信一点:方法总比问题多。咱们经过优化,最终将页面加载时间降到了650ms,仅为优化前的一半。全部优化工做中,效果最明显的就是js按需加载了。

不过按需加载也为咱们的代码结构带来了很大的冲击,极大地改变了咱们写代码的方式,也制造了不少问题,我会在下一篇《前端重构——模块化框架实践》中进行详细介绍。

by lizhouquan

相关文章
相关标签/搜索