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

标签: 未分类 | 发表时间:2012-07-09 17:34 | 作者:editor
出处:http://stblog.baidu-tech.com
  • 前言:

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

  • 应用场景分析:

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

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

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

 

       常规优化手段包括

       CSS置顶,JS置底。

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

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

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

       使用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

相关 [前端 重构 实践] 推荐:

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

- - 搜索研发部官方博客
       最近一直在做性能优化和模块化改造的工作,并完成了一次前端重构. 在这里总结出一些经验和得失来帮助大家思考. 共两篇文章,第一篇讨论性能优化,第二篇讨论模块化框架. 而之所以把这两个话题放到一起,是因为这两项工作都涉及到对前端代码进行不同程度的重构,而且模块化改造其实是我们在对性能优化做到一定程度之后发现必须要做的一件事情.

Web前端优化最佳实践

- Jimmy - 中文热文榜|最新
还有 Jason, Bixuan, 曦, 推荐,查看全部 8 个推荐. 博评 - Sting的网经发表于2010-08-08 08:41:10. Google的前端优化最佳实践 Yahoo的前端优化最佳实践. Web前端优化最佳实践之Content篇. 尽量减少 HTTP 请求 (Make Fewer HTTP Requests).

前端性能优化最佳实践

- - Web前端 - ITeye博客
如今浏览器能够实现的特性越来越多,并且网络逐渐向移动设备转移,使我们的前端代码更加紧凑,如何优化,就变得越来越重要了. 开发人员普遍会将他们的代码习惯优先于用户体验. 但是很多很小的改变可以让用户体验有个飞跃提升,所以任何一点儿小小的优化都会提升你网站的性能. 前端给力的地方是可以有许多种简单的策略和代码习惯让我们可以保证最理想的前端性能.

前端组件化开发实践

- - 美团技术团队
随着前端开发复杂度的日益提升,组件化开发应运而生,并随着 FIS、React 等优秀框架的出现遍地开花. 这一过程同样发生在美团,面临业务规模的快速发展和工程师团队的不断扩张,我们历经引入组件化解决资源整合问题、逐步增强组件功能促进开发效率、重新打造新一代组件化方案适应全栈开发和共享共建等阶段,努力“controlling complexity”.

Puppeteer前端自动化测试实践

- - SegmentFault 最新的文章
本篇内容将记录并介绍使用Puppeteer进行自动化网页测试,并依靠约定来避免反复修改测试用例的方案. 主要解决页面众多时,修改代码导致的牵连错误无法被发现的运行时问题. 目前我们在持续开发着一个几十个页面,十万+行代码的项目,随着产品的更迭,总会出现这样的问题. 在对某些业务逻辑或者功能进行添加或者修改的时候(尤其是通用逻辑),这些通用的逻辑或者组件往往会牵扯到一些其他地方的问题.

最佳实践系列:前端代码标准和最佳实践

- - 博客园_旁观者
最佳实践系列:前端代码标准. @窝窝商城前端(刘轶/李晨/徐利/穆尚)翻译于2012年 版本0.55 @郑昀校对. isobar的这个前端代码标准和最佳实践文档,涵盖了Web应用开发的方方面面,我们翻译了大部分章节,并做了注解. 渐进增强; Combo Handler; Quirks Mode; 浏览器盒子模型; 选择器特殊性; Spacer Image; CSS Sprites; PNG8;.

构建初级前端页面重构开发环境

- - 我爱水煮鱼
本文主要面对前端初级新手,是我从事前端项目外包这一年多时间里积累的经验,提供一系列的工具和资料来帮助新手更高效的从事前端开发. 但是由于本人水平有限,所以只能写一些初级的方法和工具. 没有添加诸如 grunt 这类的更高级的工具,因为我对这块目前还没有很多实战经验. 此外,关于移动端的调试开发,也很少做过,所以本文没有很多相关信息,有待进一步补充.

支付宝新首页的几点前端实践

- LiuWeifeng - 幸福收藏夹
前段时间带了3个实习生同学,做了支付宝新首页改版项目. 有一些实践可以提提,供大家参考. 其中包括了目前讨论得最火的 HTML5. 当然,也包括个人在页面性能优化上的一些经验. HTML5 的应用不仅仅是标签的应用,但她可以从标签的应用开始. 打开你的浏览器,查看源代码,你会发现
这些标准已经都用上了.

前端代码标准最佳实践:CSS

- - CSDN博客推荐文章
上一篇《 前端代码标准最佳实践:javascript》发表后,大家讨论还是很热烈,从侧面体现了前端工程师对写标准的前端代码的重视程度很高. 这些最佳标准实践并不是那个权威组织发布的,而是由大量的前端工程师们在实践过程中的经验总结,目的在于提高代码的可读性,可维护性和性能. 那么接着上一篇,我们再来谈谈CSS代码的一些标准实践.

Web 前端优化最佳实践之 Mobile(iPhone) 篇

- - 可咔酷 | 网络杂货铺
Web 前端优化最佳实践最后一部分是针对移动应用的,其实只是针对 iPhone 的,目前只有两条规则. 单个数据对象小于 25K (Keep Components under 25K). 这个似乎只是 针对 iPhone 研究的. 建议保持单个 Web 数据对象在 25 K 以下. Apple 官方信息指出可缓存到内存中的 Web 对象最大支持到 10M,但经过测试,发现也就是 25K 左右.