作者:MoLiquanKyleMo译者:前端小智出处:medium说到Web前端性能优化,有很多技巧都着重于如何降低页面加载时间的“加载时间”,例如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一直在maxed出门时间长(图中看起来很忙,要做的工作很多),需要注意是否有机会通过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的底部,它代表浏览器的MainThread在Profiling过程中被阻塞的时间。总之,我们当然希望这个时间能越短越好。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...总结目前网站非常依赖和看重Lighthouse等性能测试工具计算出来的分数,但是笔者遇到过LighthousePerformance分数满分分数。有时会出现明显的滞后和不流畅的情况。这意味着我们不能完全信任和依赖这些分数。当用户遇到性能体验不佳时,RuntimePerformance的Debugging就变得非常重要。虽然今天只是粗浅的介绍,但希望这篇文章能帮助大家在以后需要使用PerformanceTab时,不再被琳琅满目的Dashboard吓倒,而是清楚地知道如何找到问题的瓶颈。代码部署后可能存在的bug,无法实时获知。事后为了解决这些bug,花费了大量的时间在日志调试上。顺便推荐一个好用的bug监控工具Fundebug。原文:https://medium.com/starbugs/%...交流有梦想,有干货,微信搜索【大招天下】关注这位大清早还在洗碗的洗碗小智。本文GitHubhttps://github.com/qq44924588...已收录,有完整的测试站点、资料和我的一线厂商访谈系列文章。
