本指南将介绍如何创建高性能 CSS 动画。
如需了解这些建议背后的 理论,请参阅为什么某些动画运行缓慢?。
浏览器兼容性
本指南推荐的所有 CSS 属性都具有良好的跨浏览器支持。
transform
opacity
will-change
移动元素
如需移动元素,请使用 translate 或 rotation 关键字值,这些值是
transform 属性的。
例如,如需将某个项滑入视图,请使用 translate。
.animate {
animation: slide-in 0.7s both;
}
@keyframes slide-in {
0% {
transform: translateY(-1000px);
}
100% {
transform: translateY(0);
}
}
使用 rotate 旋转元素。以下示例将元素旋转 360 度。
.animate {
animation: rotate 0.7s ease-in-out both;
}
@keyframes rotate {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
调整元素大小
如需调整元素大小,请使用 scale 关键字值,它是
transform 属性的值。
.animate {
animation: scale 1.5s both;
}
@keyframes scale {
50% {
transform: scale(0.5);
}
100% {
transform: scale(1);
}
}
更改元素的可见性
如需显示或隐藏元素,请使用 opacity。
.animate {
animation: opacity 2.5s both;
}
@keyframes opacity {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
避免使用会触发布局或绘制的属性
在将任何 CSS 属性用于动画(transform 和 opacity 除外)之前,
请确定该属性对 渲染流水线 的影响。
除非绝对必要,否则请避免使用任何会触发布局或绘制的属性。
强制创建图层
如为什么某些动画运行缓慢?中所述, 将元素放置在新图层上可让浏览器重新绘制这些元素,而无需 重新绘制布局的其余部分。
浏览器通常可以很好地决定应将哪些项放置在
新图层上,但您可以使用
will-change 属性手动强制创建图层。
顾名思义,此属性会告知浏览器此元素将以某种方式发生更改。
在 CSS 中,您可以将 will-change 应用于任何选择器:
body > .sidebar {
will-change: transform;
}
不过,规范
建议您仅应将其添加到始终即将发生
更改的元素。例如,这可用于用户可以滑入和滑出的边栏。如果元素不经常更改,请在可能发生更改时使用 JavaScript 应用 will-change。请确保为浏览器提供足够的时间来执行必要的优化,并在更改停止后移除该属性。
如需在不支持 will-change 的浏览器中强制创建图层,您可以设置 transform: translateZ(0)。
调试运行缓慢或出现故障的动画
Chrome 开发者工具 和 Firefox DevTools 可以帮助您找出动画运行缓慢 或出现故障的原因。
检查动画是否会触发布局
使用 transform 以外的其他内容移动元素的动画可能会运行缓慢。以下示例比较了使用 transform 的动画与使用 top 和 left 的动画。
.box { position: absolute; top: 10px; left: 10px; animation: move 3s ease infinite; } @keyframes move { 50% { top: calc(90vh - 160px); left: calc(90vw - 200px); } }
.box { position: absolute; top: 10px; left: 10px; animation: move 3s ease infinite; } @keyframes move { 50% { transform: translate(calc(90vw - 200px), calc(90vh - 160px)); } }
您可以在以下两个示例中对此进行测试,并使用 DevTools 探索性能。
Chrome DevTools
- 打开性能 面板。
- 记录运行时性能 在动画发生时。
- 检查摘要 标签页。
如果您在摘要 标签页中看到渲染 的非零值,则可能意味着您的动画正在使浏览器执行布局工作。
Firefox DevTools
在 Firefox DevTools 中,瀑布图 可以帮助您了解浏览器花费时间的位置。
- 打开性能 面板。
- 在动画发生时开始记录性能。
- 停止记录并检查瀑布图 标签页。
如果您看到重新计算样式的条目,则意味着浏览器必须返回到 渲染瀑布图 的开头才能渲染动画。
检查是否存在丢帧
- 在 Chrome 开发者工具 中打开 渲染 标签页。
- 选中 FPS 计数器 复选框。
- 在动画运行时观看这些值。
请注意 FPS 计数器 界面顶部的帧 标签。
这会显示类似 50% 1 (938 m) dropped of 1878 的值。高性能动画的百分比很高,例如 99%,这意味着丢帧很少,动画看起来很流畅。
检查动画是否会触发绘制
与某些属性相比,浏览器绘制某些属性的开销更高。例如,任何涉及模糊(例如阴影)的内容的绘制时间都比绘制红色框长。这些差异在 CSS 中并不总是很明显,但浏览器 DevTools 可以帮助您确定需要重新绘制的区域,以及其他与绘制相关的性能问题。
Chrome DevTools
- 在 Chrome 开发者工具 中打开 渲染 标签页。
- 选择绘制闪烁 。
- 在屏幕上移动指针。
如果您看到整个屏幕闪烁,或者您认为不应更改的区域突出显示,请进一步调查。
如果您需要确定特定属性是否会导致 与绘制相关的性能问题,Chrome 开发者工具中的绘制性能分析器可以帮助您。
Firefox DevTools
- 打开设置 ,然后为 “切换绘制闪烁”添加工具箱按钮。
- 在要检查的页面上,开启该按钮,然后移动鼠标或滚动鼠标,以查看突出显示的区域。
在合成阶段添加动画
在可能的情况下,将动画限制为 opacity 和 transform,以使动画保持在渲染路径的合成阶段。使用 DevTools 检查路径的哪个阶段受到动画的影响。
使用绘制分析器查看是否有任何绘制操作的开销特别高。如果您发现任何问题,请检查是否有其他 CSS 属性可以提供相同的外观和风格,但性能更好。
请谨慎使用 will-change 属性,仅在遇到性能问题时才使用。