淘宝新势力周H5性能优化实战

前言

淘宝新势力周(春上新)是命运石kimi链路(H5链路)第一次承接S级大促,面对S级大促内容丰富且复杂的页面需求,kimi链路遇到了一些性能问题,在未进行性能优化以前,搭建出来的页面,业务方广泛反馈页面卡顿严重,没法滑动。android

由于时髦女装会场是反馈比较严重的页面之一,因此我以时髦女装会场为例子,介绍下此次性能优化的具体方案。时髦女装会场页面模块在18个左右,页面上的img标签数量在200左右,页面总长度 31208px,以iPhone6页面一屏736px为标准,总共能分为42.4屏左右。为何我要特别把img标签写出来呢?由于此次的性能卡顿主要的缘由是由于错误使用图片懒加载引发的。web

经过performance图排查性能问题

现代的web性能优化离不开chrome devtool里performance的帮助,咱们先来看一张未优化以前 performance的截图chrome

未优化前

这张performance图咱们主要看三个部分:第一个是最上面FPS红线的部分,红线表明着这段时间内未达到60FPS每帧;第二部分是Frames的耗时,勾选了Screenshots后咱们能看到每帧的耗时;第三部分是下面函数耗时,咱们能从函数耗时里分析出来究竟是哪段代码block住了页面渲染,致使卡帧。缓存

从上面的图能够看到最长的一帧耗时3.37秒,这致使FPS都快接近0了。性能优化

把函数耗时图拉大分析里面耗时最长的函数,能够看到耗时最长的函数是inview函数,这个函数是图片懒加载库里面检查当前图片是否在屏幕中间的函数。多线程

图片懒加载库的基本逻辑是:当调用初始化函数时当即检查当前页面上全部未真正加载的图片,判断是否须要加载。当页面进行滑动时,重复检查全部图片的逻辑。异步

此次性能问题的缘由和解决方案

卡顿掉帧的缘由:此次搭建出来的页面使用的是外包同窗开发的业务模块,在模块内部手动调用了lazyLoad初始函数,因此每初始化一个模块就会当即检查全部未加载图片,当页面上图片数量不断增加的时候,inview函数的耗时也不断增长,检查一个图片是否在页面的耗时是2ms~5ms,若是页面中有100个图片未加载当页面滑动时每一次检查会耗时200ms~500ms,若是检查是同步操做的话,掉帧几乎没法避免。函数

优化方案:以前的其余链路的优化方案是模块懒加载,而后lazyload统一调用,可是由于此次离上线时间较紧张,让外包返工改模块风险较大,因而有另外的一个优化方案:图片懒加载库的异步化,只要避免函数执行耗时过长阻塞渲染,就能避免卡帧,假设咱们有100张图片,咱们分多批次进行检查,避免一次检查全部图片阻塞渲染。另外针对模块初始化时频繁的检查全部图片的问题,咱们给这段逻辑加上debounce函数和图片缓存队列。性能

优化的过程

优化1.0:

在我接手以前,有一版优化是将模块的渲染经过setTimeout函数改为异步的;这个优化是几乎没有效果的,优化后页面依然卡顿掉帧,由于这个优化并无找到页面卡顿的缘由。起码也应该将setTimeout改为RAF。固然模块的延时加载并不能解决卡顿问题,可是模块的懒加载能解决一部分问题。下面咱们看一张使用模块懒加载后的performance图优化

模块懒加载后,一长条红色块已经变成了短条的红色块,可是由于模块内部单独使用图片懒加载致使频繁检查全部图片是否在可视范围内的问题仍是没有获得解决,最长的一帧达到855ms,依然存在掉帧。

优化2.0:

图片懒加载异步版本:经过对图片懒加载库的改造,一、初始化时加上debound优化和图片缓存队列,二、分批检查图片。咱们在看一下优化后的performance图

红色的条块也消失,看下面函数执行变的又长有尖,这是由于检查图片的操做变成异步分批了。

图片懒加载库改造时遇到的问题:

在将图片懒加载改形成异步的时候遇到了一个问题,就和Java多线程同样,不少时候异步咱们也但愿是有序的异步。

分批检查的有序是比较容易保证的,将图片分红多批,一批一批进行,再最后一批结束任务。可是问题出在分批检查和图片懒加载模块初始化存在交替运行的状况,而这两个任务都会改变一个变量。若是不能解决这个问题,就会出现图片有时候能正常加载,有时候加载不出来的状况。因此有说法是,大部分偶现的问题都是异步并行的问题。

解决这个问题的思路也比较常见,就是经过锁,当一个操做异步变量的任务开启,咱们的锁自增1,完成异步任务时自减,图片懒加载库的图片缓存初始队列等到异步锁释放后再进行检查,不然存入缓存队列,等待下一帧再检查。

总结

优化事后,对应常见的机型基本能保证页面流畅不卡顿。chrome的performance图基本上和真机操做的状况保持一致,若是performance出现掉帧,那iPhone6s上和android上基本也会出现掉帧,可是iPhone7以上的机器却可能感觉不明显。经过performance可以快速定位掉帧的问题,经过解决这些问题实质性的优化页面性能,而不是经过猜想进行无效优化。

相关文章
相关标签/搜索