如何创建高性能 CSS 动画

本指南将教您如何创建高性能 CSS 动画。

请参阅为什么有些动画速度很慢?,了解这些建议背后的理论。

如需移动元素,请使用 transform 属性的 translate 或 rotation 关键字值。

例如,如需将某个项目滑入视图中,请使用 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);
  }
}

如需调整元素的大小,请使用 transform 属性的 scale 关键字值。

.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 的浏览器(很可能是 Internet Explorer)中强制创建图层,可以设置 transform: translateZ(0)

Chrome 开发者工具和 Firefox 开发者工具提供许多工具,可帮助您弄清楚动画运行缓慢或出现故障的原因。

使用 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));
  }
}

 

  1. 打开性能面板。
  2. 在动画播放时记录运行时性能
  3. 检查 Summary 标签页。

如果您在 Summary 标签页中看到 Rendering 的非零值,可能表示您的动画让浏览器执行布局工作。

示例会导致渲染工作

示例不会导致渲染工作

在 Firefox 开发者工具中,Waterfall 可以帮助您了解浏览器将时间花在何处。

  1. 打开性能面板。
  2. 在动画播放时开始录制性能。
  3. 停止录制并检查 Waterfall 标签页。

如果您看到重新计算样式的条目,则表示浏览器必须返回到呈现瀑布流的起始位置才能渲染动画。

  1. 打开 Chrome 开发者工具中的渲染标签页
  2. 选中 FPS 计量器复选框。
  3. 在动画运行时观察值。

请注意 FPS 计量器界面顶部的标签。 这会显示类似 50% 1 (938 m) dropped of 1878 的值。高性能动画的百分比较高(例如 99%),这表示只有很少的帧丢失,并且动画看起来很流畅。

示例会导致 50% 的帧丢失

示例仅会导致 1% 的帧丢失

浏览器在某些属性上绘制的开销要高于其他属性。例如,任何涉及模糊处理的内容(例如阴影)的绘制时间要比绘制红色框的时间长。在 CSS 中,这些差异并不总是很明显,但浏览器开发者工具可以帮助您确定需要重新绘制的区域,以及其他与绘制相关的性能问题。

  1. 打开 Chrome 开发者工具中的渲染标签页
  2. 选择 Paint Flashing
  3. 在屏幕上移动指针。

在这个来自 Google 地图的示例中,您可以看到正在重新绘制的元素。

如果您看到整个屏幕闪烁,或者发现您认为不应更改的区域突出显示,请进一步调查。

如果您需要确定特定属性是否会导致与绘制相关的性能问题,可以使用 Chrome 开发者工具中的绘制性能分析器

  1. 打开 Settings,然后为 Toggle Paint flashing 添加 Toolbox 按钮。
  2. 在您要检查的页面上,开启该按钮,然后移动鼠标或滚动以查看突出显示的区域。

请尽可能将动画限制为 opacity 和 transform,以使动画保留在渲染路径的合成阶段。使用开发者工具检查路径的哪个阶段正受动画影响。

您可以使用绘制性能分析器查看任何绘制操作是否特别耗费资源。如果您发现任何信息,请检查其他 CSS 属性是否提供相同的外观和风格且性能更好。

请仅在遇到性能问题时谨慎使用 will-change 属性。

阅读余下内容
 

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注


京ICP备12002735号