避免掉帧的关键是只用transform和opacity做过渡,因其走GPU合成层、跳过重排重绘;禁用left、width、background-color等触发重排或重绘的属性,且不可混用或使用transition: all。

避免过渡掉帧的关键,是让浏览器只做它最擅长的事:不重排、不重绘,只合成。只要一次过渡里混入任一布局属性(比如 left、width、margin),整条过渡就会降级到 CPU 渲染,60fps 很快就崩。
只过渡 transform 和 opacity
这两个属性能走 GPU 合成层,每帧只需移动纹理或混合像素,完全跳过 Layout 和 Paint 阶段。其他属性哪怕看起来“能动”,实际都伴随开销:
- ✅ 推荐:
transition: transform 0.3s, opacity 0.3s; - ❌ 避免:
transition: left 0.3s, width 0.3s, background-color 0.3s;—— 光一个left就拖垮全部 - ⚠️ 注意:
color、background-color属于重绘级,低频可用;但高频或叠加多个时,也会吃掉帧率
别用 transition: all 或模糊简写
all 看似省事,实则是性能地雷。JS 改个 z-index、visibility 甚至 outline,都会意外触发整套过渡规则。
- ✅ 明确列出:
transition: transform 0.25s ease, opacity 0.2s linear; - ❌ 慎用简写:
margin、padding、border这类会隐式触发多个子属性变化,行为不可控 - ? 替代方案:要用位移就全用
transform: translateX();要缩放就用scale(),别混搭top+transform
防止动画中偷偷触发重排
即使用了 transform,如果 JS 在过渡过程中读取 offsetHeight、getBoundingClientRect() 或写入 margin,浏览器会立刻强制同步 layout,打断渲染流水线。
立即学习“前端免费学习笔记(深入)”;
- ? 检查方式:Chrome DevTools → Performance 面板录制动画,看是否有密集的 “Layout” 或 “Recalculate Style”
- ? 动画期间避开:
el.offsetHeight、el.scrollTop、window.getComputedStyle(el).height - ? 替代思路:把需要的尺寸值提前缓存,或改用 CSS 自定义属性 +
calc()计算
will-change 要动态加,不要全局塞
will-change: transform 不是加速开关,而是提示浏览器“这个元素即将变化,请提前建图层”。静态加、乱加、加太多,反而占内存、升功耗,尤其在移动端容易更卡。
- ✅ 正确姿势:JS 动画开始前 1–2 帧设置
el.style.willChange = 'transform'; - ✅ 及时清理:监听
transitionend后设回'auto';对 iOS 短动画加setTimeout兜底 - ❌ 绝对禁止:
* { will-change: transform; }或批量给列表项加


















