动画性能和帧速率

Web 上的动画可以通过 SVGJavaScript(包括 <canvas>WebGL)、CSS animation<video>、动图 GIF,甚至动图 PNG 和其他图像类型来完成。动画化 CSS 属性的性能成本因属性而异,并且动画化开销大的 CSS 属性可能导致 卡顿,因为浏览器努力达到平滑的 帧率

对于动图媒体,例如视频和动图 GIF,主要的性能顾虑是文件大小——足够快地下载文件以避免对性能产生负面影响是最大的问题。基于代码的动画,无论是 CSS、SVG、<canvas>、WebGL 还是其他 JavaScript 动画,即使带宽占用很小,也可能导致性能问题。这些动画会消耗 CPU 和/或导致卡顿。

用户期望所有界面交互都是平滑的,所有用户界面都是响应式的。动画可以帮助网站感觉更快、更具响应性,但如果处理不当,动画也会让网站感觉更慢、更卡顿。响应式用户界面的帧率为每秒 60 帧(fps)。虽然并非总是能保持 60fps,但为所有动画保持高且稳定的帧率非常重要。

使用 CSS 动画,您可以指定多个 关键帧,每个关键帧使用 CSS 定义元素在动画特定阶段的外观。浏览器会创建动画,作为从一个关键帧到下一个关键帧的过渡。

与使用 JavaScript 动画化元素相比,CSS 动画可能更容易创建。它们还可能提供更好的性能,因为它们让浏览器对何时渲染帧拥有更大的控制权,并在必要时丢弃帧。

然而,修改 CSS 属性的性能成本因属性而异。普遍认为每秒 60 帧是动画看起来平滑的速率。对于每秒 60 帧的速率,浏览器有 16.7 毫秒来执行脚本、重新计算样式和布局(如果需要),以及重新绘制正在更新的区域。缓慢的脚本和动画化开销大的 CSS 属性可能导致 卡顿,因为浏览器努力达到平滑的帧率。

渲染瀑布流

当元素动画化 CSS 属性时,浏览器用于绘制页面更改的过程可以描述为由以下步骤组成的瀑布流

Flowchart of the CSS rendering waterfall. In order, the steps are recalculate style, layout, and paint.

  1. 重新计算样式:当元素的属性发生变化时,浏览器必须重新计算计算后的样式。
  2. 布局:接下来,浏览器使用计算后的样式来确定元素的位置和几何形状。此操作标记为“布局”,但有时也称为“重绘”。
  3. 绘制:最后,浏览器需要将元素重绘到屏幕上。最后一个步骤未在此序列中显示:页面可能被分成图层,这些图层独立绘制,然后在一个称为“组合”的过程中合并。

此序列需要适合单个帧,因为屏幕直到完成后才更新。

CSS 属性成本

在渲染瀑布流的上下文中,某些属性比其他属性开销更大

  • 影响元素 **几何形状** 或 **位置** 的属性会触发

    • 样式重新计算
    • layout
    • 重绘

    例如:leftmax-widthborder-widthmargin-leftfont-size

  • 不影响几何形状或位置且不自分层渲染的属性,不会触发布局。它们会触发

    • 样式重新计算
    • 重绘

    例如:color

  • 自分层渲染的属性甚至不会触发重绘,因为更新是在 **组合** 中处理的。这些会触发

    • 样式重新计算

    例如:transformopacity

开发者工具

大多数 Web 浏览器都包含工具,可以深入了解浏览器在动画页面元素时所做的工作。使用这些工具,您可以测量应用程序的动画帧率,并在发现任何性能瓶颈时进行诊断。