分析运行时性能

用户期望页面的交互性和流畅。但是在传输到显示器的过程中每个阶段都可能出现闪烁卡顿。 接下来我们将了解用于识别和解决运行时性能降低的常见问题的工具和策略。

TL;DR

  • 不要编写强制浏览器重新计算布局的JavaScript。分离读写函数,并首先执行读取。
  • 不要使您的CSS过于复杂。使用更少的CSS和保持你的CSS选择器简单。尽可能多避免layout。
  • 总是选择不触发layout的CSS。
  • 绘画可能占用比任何其他渲染活动更多的时间。注意绘制瓶颈。

JavaScript

JavaScript计算,特别是触发大范围视觉变化的计算, 可能会降低应用程序性能。 不要让 badly-timed 或 long-running 这样的JavaScript干扰用户交互。

工具

开启一个Timeline(时间轴)录制并查找可疑的长时间Evaluate Script(计算脚本)事件。 如果你发现任何可疑事件, 您可以启用JS Profiler并重新进行录制,以获取有关调用的JS函数的详细信息,以及它们各自占用的时间。

如果你注意到你的JavaScript有相当多的可疑事件,您可能需要将您的分析提高到一个新的水平,收集一个JavaScript CPU profile(CPU分析)。CPU配置文件显示在页面的函数中花费的执行时间。了解如何在加速JavaScript执行中创建 CPU profile(CPU分析) 。

问题

下表描述了一些常见的 JavaScript 问题和可能的解决方案︰

问题例子解决方案
影响响应或动画的昂贵的输入处理程序。Touch, parallax scrolling.      
触摸,视差滚动。
让浏览器尽可能晚的处理触摸和滚动,或绑定侦听器(参见 Paul Lewis的运行时性能清单中昂贵的输入处理程序)。
Badly-timed JavaScript 影响响应、动画或者加载。用户在页面加载完成后向右滚动, setTimeout / setInterval. 优化JavaScript执行:使用 requestAnimationFrame,分散DOM操作,使用Web Workers。
Long-running JavaScript 影响响应。停止 DOMContentLoaded event将纯计算工作移到Web Workers上。 如果你需要DOM访问, 请使用requestAnimationFrame(另请参阅优化JavaScript执行)。
Garbage-y 脚本 影响响应或动画.垃圾回收(`Garbage collection`)可能在任何地方触发。少写 `garbage-y` 脚本 (参见 Paul Lewis的运行时性能清单中动画的垃圾回收

样式

样式的变化的开销是非常昂贵的,特别是当这些变化会影响DOM中多个元素的时候。任何时候对元素应用样式,浏览器必须弄清楚对所有相关元素的影响,重新计算布局,和重绘。

相关指南:

减少样式计算的范围和复杂性

工具

开启一个Timeline(时间轴)录制。 查看大量Recalculate Style[重新计算样式]事件的录制(以紫色显示)。

单击Recalculate Style[重新计算样式]事件,可以在Details(详细信息)窗格中查看有关它的更多信息。 如果样式更改需要很长时间,这是可能对性能造成很大的冲击。 如果样式计算影响大量元素,这是另一个有改进空间的地方。

长时间重新计算样式

为了减小Recalculate Style[重新计算样式]事件的影响,我们可以:

  • 使用CSS Triggers 来了解哪些 CSS 属性触发layout(布局)、 paint(绘制)和composite(渲染层合并),以及这些属性对渲染性能的最坏的影响。
  • 切换到影响较少的属性。请参阅坚持仅限和composite属性和管理层计数上的更多指导。

问题

下表描述了一些常见的 style 问题 和可能的解决方案︰

问题示例解决方案
影响响应或动画的 高开销的 style 计算。任何更改元素几何(如宽度,高度或位置)的CSS属性;浏览器必须检查所有其他元素并重做布局。避免使用触发layout的CSS
影响响应或动画的复杂选择器。嵌套的选择器强制浏览器知道关于所有其他元素的的所有信息,包括父元素和子元素。在你的CSS中,只通过一个class(类)引用一个元素。

相关指南:

减少样式计算的范围和复杂性

Layout(布局计算)

layout(或在Firefox中reflow)是浏览器计算页面上所有元素的位置和大小的过程。 web的布局模型意味着一个元素可以影响其他元素; 例如,<body>元素的宽度通常影响其子元素的宽度,等等。这个过程可能涉及到浏览器。

作为一般的经验法则, 如果在一个结构完成之前从DOM请求一个几何值,你会发现你需要“强制同步布局”, 如果频繁重复或对大型DOM树执行的时候,这可能是一个巨大的性能瓶颈。

相关指南:

工具

Chrome DevTools Timeline(时间轴)会识别网页发生的强制同步布局。这些Layout(布局)事件显示为红色。

制同步布局

Layout thrashing(布局抖动)是强制同步布局条件的重复。 出现这种情况是当 JavaScript 反复从DOM中写入和读取,这迫使浏览器反复重新布局。 若要识别布局抖动,寻找多个强制同步布局警告图案(如上面的屏幕截图所示)。

问题

下表描述了一些常见的 layout(布局) 问题 和可能的解决方案︰

问题示例解决方案
强制同步 layout 影响响应或动画。强制浏览器在传输到显示器的过程中先执行布局,导致在渲染过程中重复步骤。首先读取你的样式,然后进行写入。 (参见避免大型, 复杂布局和布局抖动)。
布局抖动影响响应或动画。一个使浏览器进入读 - 写 - 读 - 写循环周期,迫使浏览器一遍又一遍的重新计算布局。使用FastDom库,自动批量读写操作。

paint(绘制)和composite(渲染层合并)

paint(绘制)是填充像素的过程。它往往是渲染过程中开销最大的部分。如果你注意到你的页面出现任何闪动,很可能是你的页面有绘制问题。

composite(渲染层合并)是将页面绘制完成的部分放在一起,然后显示在屏幕上。 在大多数情况下, 如果你坚持compositor-only的属性,并完全避免paint(绘制), 你应该会看到性能上的重大改进, 但你需要注意过多的层数 (另请参阅坚持仅限和composite属性和管理层计数)。

工具

想知道paint(绘制)需要多长时间或多久出现一次paint(绘制)? 在Timeline(时间轴)面板上启用Paint profiler(绘制分析器),然后进行录制。 如果你的大部分渲染时间都花在paint(绘制)上,那么你的paint(绘制)应该有问题。

时间轴录制中的长时间绘制

查看rendering settings(渲染设置)菜单,以获取有助于诊断paint(绘制)问题的进一步配置。

问题

下表描述了一些常见的 paint(绘制)和composite(渲染层合并) 问题 和可能的解决方案︰

问题示例解决方案
大量绘制工作影响响应或动画。绘制大区域或昂贵的绘制 影响响应或动画。使用transforms 和 opacity 促使元素在自己的layer内移动 避免 paint(绘制)(参见 简化绘制复杂性和减少绘制区域)
过多Layer 影响性能。太多的元素使用 translateZ(0) 极度影响性能。谨慎地减少layers,仅当你知道使用它确有改善的情况方才使用translateZ(0) (请参阅坚持仅限和composite属性和管理层计数).