当前位置: 首页 > 科技观察

作为前端开发者,你必须知道的RuntimePerformanceDebug技巧

时间:2023-03-14 16:45:30 科技观察

大家好,我是小智,今天带来一篇来自KyleMo的PerformanceDebug技巧的好文,希望对大家有所帮助,早日成为一位伟大的神。PS:文文已获得授权。说到web前端性能优化,有很多技巧都是围绕着如何降低页面的“加载时间LoadingTime”。例如,CodeSplitting通过减少需要加载的BundleSize来加快加载性能。还有一些技术是针对运行时(Runtime)的优化和调优。例如,VirtualizedList通过控制渲染DOM元素的数量,或者页面的Repaint、Reflow、Composite等渲染过程所花费的时间来保持页面的流畅性,但是如何调试这些运行时指标呢?什么样的情况代表页面的性能可能存在瓶颈?动画在当今的网页中占据了非常重要的一部分,那么如何观察动画的表现呢?今天想通过这篇文章和大家分享如何使用ChromeDevtool的PerformanceTab来检测网页在执行过程中的各种性能指标,让网页的RuntimePerformance不再是你调试时的瓶颈!ChromeDevtoolPerformanceTab基础使用过ChromeDevtoolPerformanceTab的读者可能和我一样被丰富的图表和复杂的信息吓倒了,不知从何下手。诚然,Chrome的PerformanceTab提供了丰富的信息,想要在一篇文章中将其整理得透彻几乎是不可能的,所以今天我只介绍最基本的信息和图表,但我认为面对平时的工作已经足够了需要调试。那我们废话不多说,直接开始吧!要开始调试,首先要打开一个无痕窗口并访问这个网站。之所以使用tracelesswindow是为了保证chrome运行在“干净的状态”,否则性能测量结果可能会受到其他正在运行的应用程序如扩展的影响,导致出现不准确的情况。然后在键盘上输入Command+Option+I(Mac)或**Control+Shift+I(Windows、Linux)**打开Devtool,点击PerformanceTab。左上角会有两个按钮(红框块)。单击第一个开始录制。这时候就可以开始操作网页了。Devtool会记录操作网页时使用的CPU、内存、FrameRate等。指标,这种方法适用于监控页面上的某些特定行为和功能。第二个按钮“Startprofilingandreloadpage”将开始分析并重新加载页面,并在浏览器认为页面交互结束后自动停止分析。由于我要检测的是用户手动触发的页面动画,所以第一种方法比较合适。另外,如果你的网站还需要手机版,一般来说,一些MobileDevices的性能会比较差。为了测试应用程序是否可以在低级别的移动设备上流畅运行,可以选择CPU选项(图中橙色区域)并调整CPU的性能,这里我选择6xslower来模拟运行性能低下的设备。点击开始检测后,操作你要检测的功能,点击停止profiling,一段时间后Devtool会显示profiling结果。让我们来分析一下Profiling的结果吧!下面一步步拆解,先看记录FPS、CPU、NET的图表区。FPS说到衡量网页动画的性能,最直观的方式就是观察FPS(FramePerSecond),也就是经常听到的FrameRate。做动画的时候希望FrameRate能达到60FPS左右,这样用户看到的动画不容易卡顿。(有时候FPS低不一定不好,也有可能是页面没有动静。)在上图的FPS栏中,可以看到一个粉红色的条,说明这个页面可能有掉帧这会导致页面动画不均匀甚至卡顿,严重影响用户体验,我们应该尽量避免。CPU从上图我们可以看出CPU图是时间敏感的。有些版块似乎很活跃,而另一些版块似乎几乎没有运行。您可以通过将鼠标悬停在FPS、CPU和NET上来查看分析过程的完整屏幕截图。这种技术也称为擦洗,它允许我们以渐进的方式跟踪页面动画。从上面的截图我们可以看出,从用户点击重新排列并触发动画到动画完成这段时间会增加CPU占用率。CPU图表有许多不同的颜色,代表不同的工作类型。如果您想更轻松地了解图表并整合指定时间段,您可以在性能选项卡下查看合并图表。对应上面的CPU部分是一样的。灰色(System)—浏览器内部工作(这里对哪些任务进行分类,请参考这个stackoverflow问题)白色(Idle)—空闲时间黄色(Scripting)—执行JavaScript和事件处理绿色(Painting)—图像处理,屏幕绘制紫色(Rendering)——页面样式计算蓝色(Loading)——加载处理HTML(因为我是在页面加载完成后才开始profiling的,所以这个阶段就不展示了)如果你发现你的网页的CPU一直在maxedout很长一段时间(在图表中看起来很忙,有很多工作要做),需要注意是否有机会通过CodeRefactor降低CPU的工作量或拔掉不需要的功能。当然,CPU运行时间长了也不是说坏了。比如asana的官网有一些动画是无限循环的,所以CPU会一直处理一些工作。如果需求是这样的话,可能还不错,但是你可以看一下,发现掉帧比较严重,JavaScript的执行占用了大部分的CPU时间。这个时候我们可以仔细看看怎么改善丢帧问题,或者动画能不能尽量用CSS来达到同样的效果(原因是CSS架构的动画通常是通过浏览器“主执行线程”的另一个独立执行线程,详见本文)。接下来,请参阅“性能”选项卡中间部分的更详细信息部分。因为我的demo网站这里展示的信息太少,所以我选择用刚才提到的asana官网来解释这个block,篇幅关系,我只提几个我认为比较常用的指标——Memory,Frames、时序、主要、网络、体验。内存点击红色方块中的内存选项,可以方便的显示本次profiling期间网页的内存使用情况。比如通过观察蓝色JSHeap使用率的变化,我们可以大致观察到网页是否存在MemoryLeak问题,也可以了解到哪些操作可能导致内存使用率飙升。橙色方块中的垃圾桶可以强制浏览器进行GC(GarbageCollection),因为GC在JavaScript中是不可控的,所以光看代码很难找出可能导致MemoryLeak的情况。通过强制GC,我们可以观察到函数执行前后内存使用的差异。比如执行某个函数后强制执行GC。如果内存使用率仍然很高甚至更高,则可能是MemoryLeak的情况。如果您观察到GC被高频率触发,请不要太高兴。虽然可能解决了MemoryLeak的问题,但是也意味着网站使用的内存有点多了。GC的一个特点是“StopTheWorld”。因为GC也是在MainThread中执行,过于频繁可能会造成网站性能瓶颈。Frames中间块的FramesSection展示了页面中每一次UI更新的截图,每一次UI更新都可以称为一个“frame”。当UI长时间卡住无法更新时,称为“长帧”。单击Frames中显示的其中一帧,下面的摘要选项卡将显示该帧的详细信息,包括Duration、FPS和CPUTime。如果单击摘要中的屏幕截图,则可以按时间顺序逐步浏览捕获的帧。TimingTimingSection可以看到网页加载性能的一些重要指标的时间线。这些指标是:DCL(DOMContentLoaded):HTML被加载和解析(Parse)的时间点。**FP(FirstPaint)**:浏览器在页面上绘制任意像素(pixel)的时间,比如页面的背景色。**FCP(FirstContentfulPaint)**:中文意思是“第一次内容绘画”,当浏览者到达网站时,第一次显示网站内容所花费的时间,也指的是当浏览者到达网站时,第一次显示该网站内容所花费的时间。浏览器第一次显示文字或图片,第一次测试第一次显示的原因是第二次显示该网站时,浏览器已经有缓存文件,所以不会那么准确。LCP(LargestContentfulPaint):计算网页视口中最大组件的加载时间,即页面主要内容被用户看到的时间,是速度的指标。**L(onload)**:表示所有请求的资源在解析完HTML后加载完成的时间点。**TotalBlockingTime(TBT)**也会显示在PerformanceTab的底部,这意味着在Profiling过程中,浏览器的MainThread被阻塞的总时间。当然,我们希望这个时间能够越短越好。ExperienceFromExperience,你可以看出哪里会发生LayoutShift,也就是CoreWebVital中大家关心的CLS。Network依次显示爬取每个资源所花费的时间以及资源之间的依赖关系。如果您单击任何资源,您可以在下面的摘要选项卡中看到更详细的信息,例如URL、持续时间、优先级、Mime类型、编码数据大小、解码正文大小。不过笔者在调试网络相关资源时一般直接使用Devtool的NetworkTab,整体信息更加详细直观。Main(CPUFlameChart)MainSection呈现MainThread的CPU任务,以倒置的火焰图的形式呈现,表示下面的函数或任务是由上层的任务触发的。我们可以使用它来跟踪每个任务和功能的依赖关系和触发关系。如果Task的右上角出现一个红色的三角,说明这是一个很长的任务,同时也是一个警告,告诉我们可能有一些问题导致任务执行的时间过长。点击带有红色三角的任务后,会出现如上图的详细信息。有时它会指出任务在代码中的位置,以便我们更快地调试和发现潜在的问题。比如我们点击上面显示的content.js:会直接切换到SourcesTab,并显示相应的行号,这对于Debug来说非常方便。有时候你会发现除了Main之外,还有其他的Frames和Workers。这些Frames不是指刚才说的可以观察FPS的Frames,而是指网页中嵌入的iframe,Workers指的是WebWorkers等。除了MainThread之外的执行线程,PerformanceTab甚至可以调试这些,真是了不起.由于篇幅有些遗憾,其实PerformanceTab还有很多丰富的信息没有介绍,比如关于Layer,AdvancedPaintInstrumentation的信息,还有关于CallTree,Bottom更细粒度的观察-Up等SummaryTab下的CPUActivity块,建议有兴趣和需要的读者自行研究。那么,重构后的网站动画对性能有多大影响呢?了解了PerformanceTab的基本操作方法后,回过头来看看PerformanceTab中用于demo的网站的分析状态。可以看出,当动画触发时,会严重掉帧,CPU的工作量也会变得很大。主要做的是Rendering(紫色)和Painting(绿色),Idle(白色)的时间不多,可能导致无法处理用户的输入行为。按照刚刚介绍的方法,还可以进一步查看MainSection中标记为longtask的任务,发现大部分时间都花在了绘画上,而且花费的时间非常长。按照**RAILModel**的标准,这种耗时会让用户感觉页面卡顿,甚至浏览器无法及时处理用户交互触发的事件,而用户体验非常糟糕。至此,可以大致确定,这个版本的动画有很大的问题。既然确定了问题,我们再看一下动画的代码,发现这段代码是直接改变元素的顶部来实现动画的,每次都会导致页面发生变化。都需要通过Reflow重新计算Layout。但是我们应该有更好的方法来实现同样的动画效果,所以我尝试将代码改成如下:并且在transform上使用will-changeCSS属性:然后我们直接在新版网站上进行PerformanceProfiling:Yes发现帧率和CPU使用率优化了很多。从summary选项卡也可以发现,同样的时间大约是一秒。新版网页的IdleTime增加了,这意味着有更好的机会处理用户的输入,防止用户感觉整个网站都没有响应。虽然改版后还是有一些丢帧,但应该会进一步改进,不过比起之前的版本已经提升了很多。通过这个简单的例子,读者应该知道以后遇到页面卡顿或卡顿等问题时应该如何调试,以及如何比较改写后是否真的有提升。示例地址:https://github.com/kylemocode/it-ironman-2021/tree/master/css-transform-demo总结现在的网站都非常依赖和看重Lighthouse等性能测试工具计算出来的分数,但是作者我曾经遇到过LighthousePerformance分数满分,但使用时出现明显卡顿和不流畅的情况。这意味着我们不能完全信任和依赖这些分数。当用户遇到性能体验不佳时,RuntimePerformance的Debugging就变得非常重要。虽然今天只是粗浅的介绍,但希望这篇文章能帮助大家在以后需要使用PerformanceTab时,不再被琳琅满目的Dashboard吓倒,而是清楚地知道如何找到问题的瓶颈。原文:https://medium.com/starbugs/%E8%A%AB%E7%82%BA%E5%89%8D%E7%AB%AF%E9%96%8B%E7%99%BC%E8%80%85-%E4%BD%A0%E4%B8%8D%E8%83%BD%E4%B8%8D%E7%9F%A5%E9%81%93%E7%9A%84-运行时-performance-debug-%E6%8A%80%E5%B7%A7-4f0efd27b86d作者:MoLiquanKyleMo译者:FrontendXiaozhi来源:medium