requestanimationframe 本身不提升帧率,仅对齐浏览器刷新节奏;需配合不阻塞主线程、减少重排重绘、用时间戳计算进度、只动 transform/opacity、主动管理生命周期、复杂计算移至 web worker 等措施才能稳定 60fps。

直接用 requestAnimationFrame 本身不会自动“提升帧率”,它只是把动画调度对齐到浏览器刷新节奏(通常是 60Hz),避免像 setTimeout 那样盲目轮询。真正让帧率稳定在 60fps 的,是配合它做对的事:不阻塞主线程、减少重排重绘、合理管理生命周期。
用时间戳算真实经过时间,别靠帧数累加
动画持续时间必须基于时间,而不是“第几帧”。否则帧率一波动(比如掉到 45fps),动画就变慢或加速。
- 每次回调接收高精度时间戳
currentTime,记录起始时间startTime - 计算进度:
const elapsed = currentTime - startTime,再代入缓动函数 - 错误写法:
x++累加位移——这依赖固定帧率,不可靠
只动 transform 和 opacity,避开重排重绘
浏览器对这两个属性做了专门优化:它们走合成线程,不触发 layout 或 paint,GPU 可直接处理。
- 位移优先用
transform: translateX(),别用left/top - 透明度动画用
opacity,别改visibility或display - 高频动画元素可加
will-change: transform提前提示合成层创建
主动控制动画生命周期,防止资源泄漏
没取消的 requestAnimationFrame 会一直跑,哪怕元素已删、页面已切走。
- 用变量存当前帧 ID:
let animId = null - 每次回调开头检查元素是否还存在:
if (!el || !el.isConnected) return - 页面隐藏时监听
visibilitychange暂停;组件卸载时调用cancelAnimationFrame(animId)
复杂计算挪到 Web Worker,不卡主线程
粒子系统、物理模拟、路径计算等耗时逻辑,放在 Worker 里跑,主线程只负责渲染。
- Worker 处理完数据后
postMessage回主线程 - 主线程收到数据立即
render(),不掺杂计算 - 避免在 rAF 回调里调用
getBoundingClientRect、offsetHeight等强制同步布局的 API
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











