记录一次开发的优化分析历程
在公司产出的文档,粘在这里分享
性能分析工具的介绍:
1. chrome的performance面板
可以模拟手机CPU,操作如下图,有4倍CPU和6倍CPU的选项,6倍比4倍CPU更卡。
可以录制每帧的各个性能指标,录制结果如下
Summary面板中可以查看具体的数据,Call Tree面板可以查看函数调用栈
2. react的性能监控插件——why-did-you-render
能在开发 react 组件的时候及时提醒组件是否有不必要的重复渲染问题,能将每次导致渲染的数据变化打印出来,打印上一次的props和下一次的props。
import React from 'react';
if (process.env.NODE_ENV === 'development') {
const whyDidYouRender = require('@welldone-software/why-did-you-render');
whyDidYouRender(React, {
trackAllPureComponents: true,
});
}
遇到的问题
- 赛程列表滚动时卡顿
- picker组件弹出卡顿
问题分析
赛程列表滚动卡顿分析
背景:大部分战队有三四百个赛程,且产品要求每个赛程都有曝光埋点;在PC端4xCPU下会明显卡顿
猜测原因:
- 每个赛程都注册一个曝光事件,导致滚动监听事件非常多,导致页面卡顿
- dom太多,导致卡顿(问了梅瑀,知道三四百个其实不算多,不是这个问题)
通过performance面板分析出:赛程列表滚动期间,IntersectionObserver行为大量存在,说明猜测正确。
去掉列表中所有赛程的曝光埋点,问题解决了,然后就是等待列表曝光埋点的sdk功能...
picker组件卡顿分析
背景:移动端部分手机会卡顿
先通过why-did-you-render插件修复了picker组件重复渲染的问题,但仍然没解决卡顿问题,说明react重新渲染不是主要原因。
然后用performance面板,先设置6xCPU,即模拟了部分垃圾手机的CPU,但是PC端仍然不卡顿,初步怀疑是手机GPU带不动的问题(鸿蒙手机GPU渲染程序切换为Skia,确实不卡顿)。
我用自己的手机app测,发现只要用到了Antd的picker组件的页面(包括其它人写的页面),picker组件的弹出都有有些卡顿,只不过我的战队页的卡顿更明显。
然后记录性能分析数据,更具体的分析。
占比较大的各种颜色代表的意义:
- 紫色:重新计算样式和布局
- 黄色:js脚本运行,根据Summary面板的描述知道是AnimationFrame,但是其中没有调用react的相关函数,所以这里的AnimationFrame不是react的,根据document面板分析出是Antd的picker的弹出动画(tranform值一直在改变,说明是Antd是用js操作动画)
- 绿色:渲染
猜测原因:
- 之前分析过的,整个页面dom节点太多(赛程列表tab),导致GPU玩不动
- Antd的picker的弹出动画实现的问题
针对猜测原因1:
去掉dom很多的赛程列表,也是大大解决了这个问题,但赛程列表不能去掉,也不能等到切换到赛程列表的tab再去渲染赛程列表,不然渲染也会卡顿。渲染问题,用虚拟滚动也不合适,虚拟滚动有太多功能难以实现,比如曝光埋点和锚点。所以针对原因1,没有找到合适的解决方法。
针对猜测原因2:
结合之前分析的Antd的picker组件都会卡顿,分析出卡顿的其中一个原因是Antd的Picker组件的弹出动画的问题,所以就换了个picker组件尝试是否会有问题,用的是zarm.design/#/ 里的Picker组件,根据document面板分析出这个组件是用css效果做的动画的。替换后,不卡顿了,猜测原因2也成功证实。
因此针对原因2,有以下两个解决方案:
- Antd提供了PickerView组件,可以用PickerView组件自己封装一个高性能的Picker组件,用css去做弹出效果,而不是用js去做。
- 调用客户端的Picker组件。
目前是用第二个解决方案,现在还在等待客户端的Picker组件...