记一次浏览器卡顿问题的调试

565 阅读2分钟

最近的项目比较忙,好久没有写过文章了,一直想写一些东西,但是平时总是时间比较紧迫。借这篇文章,来和大家叙叙。

火焰图

浏览器卡顿的问题一般是由于javascript的同步函数执行时间过长,阻塞了浏览器事件循环中的浏览器渲染所导致的。所以在项目中遇到了阻塞的问题,大概第一时间都会想到看一下性能选项卡中是否有什么执行时间过长的函数。笔者也是想要借助火焰图,在卡顿复现的时候,通过性能选项卡记录当时的函数执行情况:

截屏2022-11-10 10.11.18.png

可以看到浏览器在不停地执行着宏任务,并且每个宏任务的已经被浏览器标红,提示异常,图片下方也提示每个宏任务的执行时长高达1秒多。放大宏任务下面所执行的函数,我们可以发现:

截屏2022-11-10 10.11.37.png

在宏任务的函数执行情况中,主要是由于Animation.update()这个动画更新函数所调用的ZRender._flush()执行的时间比较久。后来通过查询代码了解到,这个ZRender函数只有echarts这个库用到了,所以大体可以定位到,是由echarts的所导致的。并且Animation.update()函数说明这个执行时间较长的过程可能是动画更新导致的。

渲染工具

下一步我们还可以通过浏览器的渲染工具来定位,具体是echarts的那一块的频繁动画更新导致了这个ZRender._flush()函数频繁执行。

截屏2023-01-13 21.37.15.png

点击调试工具的右上角三个点,选择更多工具->渲染,之后选择“突出显示绘制区域”:

截屏2023-01-13 21.38.36.png

可以看到随着浏览器页面的不停刷新,需要重绘的地方也在闪烁亮绿色:

截屏2022-11-14 11.41.06.png

唯独只有一块最引人注目,就是左下角的这个echarts做的折线图一直在闪。说明出问题的组件就是左下角的这个折线图。

排除法

关于一些稀奇古怪的问题,排除法总是最好用的。目前已经定位了左下角的这个组件,那么我们就可以通过排除法,来一项一项地减少里面的元素,尝试寻找到底是哪个元素使整个折线图频繁刷新。

截屏2022-11-12 00.34.56.png

最终定位到竟然是因为这个带有涟漪动画的小圆点在不停地执行动画渲染,导致了浏览器卡顿。