--- title: "CSS 动画性能优化:从掉帧到 60fps" description: "分享 CSS 动画性能优化的实战经验,理解浏览器渲染管线,写出丝滑的动画效果。" date: "2026-05-20" tags: ["CSS", "性能优化", "前端"] image: "" --- ## 动画为什么会卡 浏览器的渲染管线大致是:**JavaScript → Style → Layout → Paint → Composite**。 动画卡顿的根源在于触发了 Layout 或 Paint 阶段。每次滚动或动画帧只有约 16ms(60fps),如果 Layout 或 Paint 耗时过长就会掉帧。 ## 只触发 Composite 的属性 只有 `transform` 和 `opacity` 不会触发 Layout 和 Paint,因为它们可以完全在合成器线程完成: ```css /* ✅ 推荐:只触发 Composite */ .element { transform: translateX(100px); opacity: 0.5; } /* ❌ 避免:触发 Layout */ .element { left: 100px; width: 200px; } ``` ## 使用 will-change 提示浏览器 ```css .element { will-change: transform; } ``` 告诉浏览器"这个元素即将发生变化",浏览器会提前将元素提升到独立的合成层。但不要滥用,每个合成层都会消耗 GPU 内存。 ## 使用 FLIP 技术 对于无法用 transform 替代的动画(如改变元素位置),使用 FLIP 模式: 1. **F**irst:记录元素初始位置 2. **L**ast:记录元素最终位置 3. **I**nvert:计算差值并反向应用 4. **P**lay:移除反向变换,添加过渡动画 ```javascript 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 技术。