my_nuxt_blog/content/zh/articles/css-animation-performance.md
2026-06-08 19:55:40 +08:00

1.9 KiB
Raw Blame History

title description date tags image
CSS 动画性能优化:从掉帧到 60fps 分享 CSS 动画性能优化的实战经验,理解浏览器渲染管线,写出丝滑的动画效果。 2026-05-20
CSS
性能优化
前端

动画为什么会卡

浏览器的渲染管线大致是:JavaScript → Style → Layout → Paint → Composite

动画卡顿的根源在于触发了 Layout 或 Paint 阶段。每次滚动或动画帧只有约 16ms60fps如果 Layout 或 Paint 耗时过长就会掉帧。

只触发 Composite 的属性

只有 transformopacity 不会触发 Layout 和 Paint因为它们可以完全在合成器线程完成

/* ✅ 推荐:只触发 Composite */
.element {
  transform: translateX(100px);
  opacity: 0.5;
}

/* ❌ 避免:触发 Layout */
.element {
  left: 100px;
  width: 200px;
}

使用 will-change 提示浏览器

.element {
  will-change: transform;
}

告诉浏览器"这个元素即将发生变化",浏览器会提前将元素提升到独立的合成层。但不要滥用,每个合成层都会消耗 GPU 内存。

使用 FLIP 技术

对于无法用 transform 替代的动画(如改变元素位置),使用 FLIP 模式:

  1. First记录元素初始位置
  2. Last记录元素最终位置
  3. Invert计算差值并反向应用
  4. Play移除反向变换添加过渡动画
const first = el.getBoundingClientRect()
// 修改布局...
const last = el.getBoundingClientRect()
const invert = first.top - last.top

el.style.transform = `translateY(${invert}px)`
requestAnimationFrame(() => {
  el.style.transition = 'transform 0.3s'
  el.style.transform = ''
})

小结

动画性能优化的核心就一条:尽量让动画只触发 Composite。用 transform 代替 top/left,用 opacity 代替 visibility,必要时用 will-change 和 FLIP 技术。