最近接到一个任务,首页性能优化。
目标:95分位值下
- 看到页面框架主体内容6s(优化前10s左右),优化提升40%
- 看到操作详细内容9s(优化前12s左右),优化提升25%。
侧面看出我们系统的庞大程度吧,这个不值得骄傲,项目比较悠久,历史包袱比较沉重,后面计划node同构方式去重构,但是现阶段需要一个低成本,短时间的方案去提高现有性能作为过渡。
95分位值解释
95分位值目前是我们看性能指标的一个重要参考点。
举例:收集用户打开的时间,从快到慢排列,比如是100个用户数据,95分位值就是取出第95个用户的数据做统计。 50分位值就是第50个人的数据。
为什么是95%,因为跟进高T的优化经验,95分位值的数据取点最能放大问题。50,80的取点暴露的问题不明显。
当我把最慢的那一批人的性能优化好了,哪些快的自然就解决了。
优化难点
- 面试经常问到的页面优化点,例如图片合并,js合并,css合并,js压缩等等都已经做了。常规优化点没有什么空间可以优化。
- 代码比较老。注释上面都是12-13年的代码。
- 改动需要尽量的少,功能点不能改,时间比较紧张,QA没有人力支援,所以需要代码改动比较小的情况下(修改必须可控),不重构的情况下挖掘优化点。
任务拆分
优化性能这种任务其实比较难制定计划,除非经验特别丰富。
第一步:是梳理代码
当然也不是看所有的老业务代码,看的重点是看各个模块的加载逻辑,展现逻辑,看入口即可。
第二部:删遗留代码
大概了解整个首页的初始化流程后,梳理了简单的逻辑后,发现第一个任务,删代码。
梳理大概结构后,目测有大量下线功能的代码任然遗留在系统中,之前的下线逻辑应该是仅仅屏蔽了入口,而没有清理代码。
所以我第一个具体的工作就是找出下线的业务代码并将他清理,不完全统计,清理代码量开发环境下至少5W行。
清理代码好处很多:
- 减少无用代码的初始化消耗
- 减少静态资源
- 让代码更加清晰,减少无用代码的干扰
删除无用代码其实是个脏活,吃力不讨好,删除的代码如果还有地方引用,那么删除了就是引入了一个bug。
删除代码这个工作又没有什么显性的收益,还费工费时。其实就是一个里子的工作,把大家看不到的地方做好。
第三部:优化初始化逻辑
尽量让不是完全依赖的ajax并行,减少串行。当前系统有两个展示模块有串行关系。梳理业务后,找出首页加载的默认逻辑,将串行调整成为并行。
这里是修改代码的地方之一,修改越少越好,因为一旦修改多了,就不好控制了,就需要QA介入,那么整个项目的周期就会大大延长。
第四部:ajax预取
这个是上一个项目经验积累,在加载模块静态资源前,可以并行的请求这些模块的ajax内容。原本逻辑是,加载完毕各个模块的静态资源,然后模块内部开始加载静态资源需要的ajax。这样就避免不了静态资源的请求和静态资源里面ajax的请求形成了一个串行关系。
预取的一个明显优势是,ajax可以提前
节省的时间 = min(ajax请求时间,静态资源加载时间)
。
这里是修改的另外一个地方:同理,这个地方没有业务逻辑,所以需要和业务完全解耦着做。
第五部:优化打包合并
打包这部分难度比较大,优化空间也相对较多。
这里分了两部分:
一:首屏不展示部分按需加载
目前看很多应该按需加载的内容全部都合并到了一起,放在首屏加载了。例如点击一个按钮出来一个操作页面弹框。其实这个弹框的代码首屏展示是完全不需要。
当时注释:
代码加起来压缩完大概200kb左右,没必要拆的太细,如果代码达到500KB以上,再进一步考虑细拆
实际情况是,这个部分的代码压缩混淆后达到了1.1MB(坑爹啊)。
这种情况就是当初开发人员设想是美好的,后续业务开发人员没有意识或者了解到当初的规定,业务越来越多,代码也就越来越多。
这种情况其实比较常见,因为打包合并这种其实是尽量对业务人员透明的,这种合并后的内容,其实在开发环境体现不出来,只有刻意的压缩代码和优化时才能注意到。
容易忽视的部分就是容易出现问题的地方。
二: 打包合并重复的部分删除
还是上面的原因,打包合并对于开发人员和开发环境透明,很长一段时间后,会发现大量打包重复,比较明显的就是底层依赖库个个文件重复引用。这种不会引发bug,但是会影响首屏静态资源的加载和静态资源的解析。
一和二的成果很明显:静态资源网络压缩后(gz),1.9mb优化到了1.1mb,整体提升了42%。
三: 疑难散文件清理
之前优化过几次散文件,由于成本比较大,遗留了一些散文件。这次就是集中处理了一下,散文件其实是比较严重的,一个散文件就会浪费一个请求。95分位值下,一个散文件可能就是100ms的影响。所以不要小看散文件对于性能的影响。
成果是减少5个js静态资源请求,2个css请求。
优化感受
这些优化本周会上线,期待数据会比较好看。如果本周效果不是很明显,后面的优化空间其实就非常小了,暂时不考虑cdn,依赖后端这些方法,仅仅从静态资源出发。
优化其实就是一个没有那么明确计划的任务,往往有可能对着页面一遍一遍看加载流程或者把源代码挨个扫一遍找找感觉,一个突发奇想,一个奇淫技巧,一个业务展示效果的调整就能达到。
后续看看是否达标,性能不达标的话,还会有《我是如何优化网站首页性能的(番外篇)》。/(ㄒoㄒ)/~~
优化感受2
优化就是细节完善,举个例子:
- 有时一个js散文件可能多消耗50ms,但是一旦出现10个,20个影响就叠加起来了。
- 一个底层库被重复打包了,可能多了几千行,静态资源增加了几k,加载上可能就是几ms,加上与解析几ms。但是一旦重复的静态资源多了,问题就来了。上万行,上百K的资源都是拖慢系统的根源。难以想象我这次粗滤的清理了一下,清理了0.6MB的资源。
优化没有止境,这一版上线后,肯定还有很多遗留的地方,后续看看效果,继续优化。
ps:最后发现自己整理完这么多,也没有做什么,感觉后面还需努力