当前位置: 首页 > Web前端 > HTML

【技术干货】前端性能优化-快速定位代码bug

时间:2023-03-28 11:54:36 HTML

分享者:MarkWu(吴银波)云智慧前端工程师,致力于云智慧大屏产品及ITSM、DOMM、DOEM和定制化开发其他产品线,具有丰富的前端性能优化和开源项目经验。背景介绍:不知道大家有没有遇到过这些情况:通知说某个bug必须在下周一之前解决,现在已经是周五下午了;网络版关闭的前一天,得知客户机器性能不好,出现某个bug打不开。一页,已是晚上十点;晚上2点接到电话,某个系统现在不行了,不过明天给客户领导演示一下,你电脑还没带回家。。。如果你有同样的情况,那么恭喜你,这只是一个开始……如果没有,那么恭喜你,你迟早会遇到的……嗯,如果我们能想办法快速定位问题的话,大概率是这样的可以避免问题,大大提高效率。下面结合具体的例子分享下我是如何使用Performance面板和console面板来定位问题的。最后我也给大家分享一个用这个方法优化的轮子。1、Performance性能分析面板现在看Performance性能分析报告:可以看到时间轴包括FPS、CPU、网络等;本节主要关注FPS,观察是否有红色区域。可以在js执行过程下方定位主要指标对应的位置,观察程序的哪一部分影响了页面的性能,可以帮助我们快速确定需要优化的代码位置;还要注意总阻塞时间,这是对当前页面运行是否流畅的综合评价,应尽可能减少阻塞时间;最后注意总结部分,比较脚本执行和渲染时间,确定JS执行和页面渲染哪个是主要优化对象(优化往往是并行的)。下面两个例子分别着重优化JS执行效率和页面渲染效率。JS执行效率主要是降低代码空间复杂度,减少不必要的内存开销,避免深拷贝,及时清除定时器等;页面渲染效率主要是降低页面权重尽量同步页面动画和显示帧率刷新。2、JS执行性能优化示例DOMM定制项目存在的问题:现场某场景G6拓扑组件节点数量过多,浏览器卡顿,无法重现开发环境。分析:页面假死一般是js线程阻塞,栈内存溢出,或者页面动画过于复杂导致css线程卡死,布局抖动频繁等。性能分析:从上图可以看出js执行时间比较长,渲染时间比较短。这种情况先排除css线程和布局抖动的影响,确定问题出在JS执行上。而且,在优化页面性能时针对这种情况进一??步优化页面渲染效率是困难的,也是不经济的。这时候的重点也是在JS执行效率上。使用控制台打印各个环节的耗时,判断问题代码。通过分析Performance的Main,结合代码分析,确定问题代码区域,在代码执行的主节点上打印耗时,细化耗时较多的区域代码。完成问题代码。计算耗时打印耗时打印情况:分析:可以看到这部分JS代码的总执行时间为1027ms,其中计算节点和计算连接耗时最长,执行了两次,并且设置了防抖功能。分析:设置防抖后,这段JS的总执行时间为599ms,打印出“计算连接”部分需要时间。细化耗时打印:a.“连接计算”耗时分析:“计算连接”部分的JS代码被多次引用,继续细化这部分耗时打印;b.单次连接耗时分析:“连接耗时”是节点间单次连接的耗时计算,执行次数多且单次耗时不短,继续细化这部分代码,并发现可疑的代码深拷贝。C。深拷贝耗时分析:“克隆耗时”打印规则与“连接耗时”类似,存在耗时较长的问题。使用累计计时的深拷贝打印整体耗时耗时。分析:深拷贝累计打印3次,总耗时679ms,占比较大。耗时定位:每次深拷贝耗时较长,需要优化深拷贝算法或连接计算逻辑避开深拷贝分析:拷贝层次过深,导致耗时较长,使用浅拷贝反而。优化深拷贝耗时后的打印分析:浅拷贝总打印时间为6ms,相比原来的679ms非常短。动画渲染分析不能确定现场部署没有问题。我们来看看拓扑节点数量对JS执行和页面渲染效率的影响。i加载200个节点前端渲染耗时ii加载1个节点前端渲染耗时分析:可以看到200个节点的页面渲染时间和单节点页面渲染相差不大,主要是执行ofJS脚本多用了25ms,因为站点最大节点数超过800个的情况下,经过简单计算发现耗时相比原来的1027ms还是有很大提升的。3、动画渲染性能优化实例遇到一个问题:之前开发大屏,本地运行没有问题,但是联调测试发现右边有一个滚动组件模块(有4个)什么都没有,并且界面正常返回。这也是正常的。最后发现接口返回了190多条数据,前端渲染了所有这些组件,导致模块卡顿。先来看一下现场效果图。左边是地图、轮播图、饼图和轮播图。中间是两个拓扑链接图轮播。下面是4张echarts图表。右边是4个滚动模块(图片不全)。现在除了要解决上面的问题,还要做好整个大屏的同步加载。↓直播大屏显示效果分析:下面我们来看这个问题。由于所有的加载都会导致模块卡死,那么就采用逐个加载(onebyone)的方式来代替全部加载。现在演示一个单体效果:onebyone模式单体模块效果说明:绿框为可见区域,红框为滚动组件,渲染固定数量的滚动单元,使用CSS控制页面动画,定时刷新相应的滚动单元。Onebyone模式单模块性能分析面板分析:单个组件的运行造成了JS线程阻塞,JS脚本的执行和渲染都相当耗时。Onebyonemode4modulesPerformanceanalysis面板分析:执行JS脚本和渲染耗时较长,导致JS线程阻塞时间长,页面布局抖动掉帧。代码分析:每更换一个滚动单元就会引起重排,然后每个模块都是这样,4个模块叠加会不断引起页面重排,然后这里用js控制布局,导致不一致间距。当时的改进方案是减少重排次数,更换布局方案。如何减少重排次数?“一次计算整个transitionpanel,每次transitionpaneltransition后更新整个panel,换成flex布局。”下面我们来看看这个方案的效果:twomove模式单模块情况twomove模式单模块性能分析面板分析:单组件运行时没有JS线程阻塞,单模块产生的dom数量相同屏幕比onebyone模式多,所以优势不明显。Twomove模式4个模块性能分析面板分析:JS脚本执行和渲染耗时差不多,JS线程阻塞时间减少,页面不会出现布局抖动或掉帧,多模块的优点是杰出的。4.总结通过Performance性能分析确定主要优化方向。对于JS执行,可以通过控制台结合Main指标定位问题代码。对于页面渲染,应减少页面重排序以减少页面渲染消耗,重点优化阻塞时间和页面掉帧问题。继续优化该组件的结果,增加endWithNum属性,控制一个循环完成后分隔的单元数,修复一些bug,包括页面不可见后raf停止,css继续运行。经过测试以确保稳定性,并添加了一些配置属性以使轮子无反应。最后:轮子共享react-rollfreereact-rollfree适用于各种滚动组件场景,包括文字、图片、动画等,支持大数据动态更新,基本可以覆盖各种滚动动画场景。后期会加入弹幕模式,拓展更多的应用场景。下载方式:npminstallreact-rollfree源码地址:https://github.com/Markuuuu/r...具体配置:```*@animationDirectionboolean--滚动方向,默认为从下到上,从从左到右``````*@animationTime数字--过场动画时间单位:S``````*[@children](https://my.oschina.net/children117cl)[]--滚动组件,支持隐式传递``````*@childrenUpdateModelstring--数据更新后更新列表,'now'立即更新,'later'运行后更新``````*@contextHeightnumber--单轮广播组件高度``````*@contextWidthnumber--单个轮播组件宽度``````*@endWithNumnumber--末尾空置滚动单元数`````*@heightnumber--scrollFrameheight``````*@horizo??ntalboolean--水平和垂直旋转木马`,默认水平`````*@pauseWithHoverboolean--默认启用,鼠标悬停组件滚动停止``````*@showBorder布尔值--是否显示辅助设计边界``````*@widthnumber--滚动框宽度```使用:`````````{Rollingdom[]}`````````react-rollfree默认效果1000个滚动模块效果图(实现矩阵特效)写到最后:更多智能运维资讯,请关注云智AIOps社区云智慧产品开源地址:Github:https://github.com/CloudWise-OpenSourceGitee:https://gitee.com/CloudWise