硬件加速的核心原则是“专款专用”:仅对正在执行动画的元素临时启用,并配合 transform 和 opacity 使用,同时必须禁用 left、top、height 等会触发强制布局(reflow)的属性——否则,动画掉帧、卡顿只是轻微后果,在低端 Android 设备上,甚至可能直接导致页面无响应或卡死。

先记住一个核心结论:只对正在动画的元素临时启用硬件加速,配合 transform 和 opacity 动画,禁用 left/top/height 等触发布局的属性——否则动画会掉帧、卡顿,甚至在低端 Android 上直接卡死。
为什么 translate3d(0, 0, 0) 不能全局加在 .loading 类上
它并非简单的“加速开关”。其真实作用是向浏览器请求一个独立的合成层(compositing layer)。滥用该属性会导致 GPU 显存急剧上升,尤其在 Android WebView 中,内存占用增加后,滚动反而变得更卡,动画速度也明显下降。更关键的是,如果父容器带有 overflow: hidden、filter 或 opacity < 1,这些属性会压制子元素的提层行为,导致 translate3d 失效,等于白写。
正确的做法是:
- 只在动画开始前 1 帧加上:在
el.style.transform = 'translateY(0)'前,先执行el.style.willChange = 'transform' - 动画结束后,监听
transitionend事件,立即把willChange设回auto - 对于静态旋转图标(如
@keyframes spin),应单独加一个类,比如.spin-3d { transform: translate3d(0, 0, 0); },千万别写死在基础样式里
移动端旋转 Loading 必须显式设置 transform-origin
iOS 12 到 14 的 WebKit 存在一个隐藏很深的 bug:如果父容器带有 perspective 或其他 transform,而子元素没有显式设置 transform-origin,旋转动画会在中途卡住,或者干脆跳回 0 度。
所以,以下几点必须注意:
transform-origin: center必须写,不能依赖默认值- 避免使用
from { }+to { }以外的多关键帧,旧版 Safari 解析时容易出问题 - 动画时长建议设为
0.8s,这个时长比1s更符合人眼对流畅感的感知阈值 - 别用
currentColor控制边框色——系统深色模式切换时,它不会实时响应,得手动 toggle class 或触发重绘才行
列表项交错加载动画别靠 JS 滚动监听
滚动时逐项触发 animation 或用 JS 判断视口,这在低端 Android 上简直就是灾难,频繁的重排重绘会直接导致掉帧。
这些方案值得参考:
- 用
:nth-child(n)配合transition-delay实现 CSS 原生交错,总延迟控制在 ≤ 600ms 以内 - 必须包裹在
@media (prefers-reduced-motion: reduce)里做降级处理,同时重置transform和opacity,否则残留的位移会导致内容错位 - 入场只加一个类(如
.is-visible),靠transition触发效果,千万别写transition: all——一旦改了margin或背景色,整段动画就退回到 CPU 渲染,性能全无
图片懒加载动效要防 iOS Safari 的“唤醒延迟”
iOS Safari 的 IntersectionObserver 在页面刚加载时可能不触发,这不算 bug,而是 WebKit 的 lazy rendering 行为导致的。
应对策略如下:
DOMContentLoaded事件后,延迟 16ms 调用一次observer.takeRecords(),强制初始化观察器- 初始占位必须用
aspect-ratio+background-color,禁用height: auto,否则加载瞬间的重排会导致图片抖动 - 动效只使用
opacity和transform,并提前加上will-change: opacity, transform - 回调里绝对不要读取
offsetHeight或getBoundingClientRect(),否则同步回流会卡住动画帧,性能直接崩掉
很多时候,真正的卡顿并不出在动画本身,而是出在提层时机、父容器压制、系统偏好未处理、或 iOS 特定渲染行为上。写完动画后,建议打开 Chrome DevTools → Rendering → Layer Borders,看看有没有绿色边框出现。如果没有,那就要回头排查:是不是被 overflow 拦住了?还是关键帧里混进了 width 这种危险属性?
