javascript动画节奏控制核心是requestanimationframe(raf)结合时间戳计算真实间隔,避免settimeout/setinterval;通过timestamp - lasttime判断是否达到目标间隔(如100ms),满足则执行并更新lasttime,否则继续raf循环,确保稳定、防跳帧、可多节奏共用同一raf主循环。

JavaScript 中动画帧的节奏控制,核心在于合理使用 requestAnimationFrame(简称 rAF),并结合时间戳(timestamp)做精确的时间差计算,而不是依赖固定间隔的 setTimeout 或 setInterval。
用 rAF + 时间戳实现稳定帧率
rAF 本身不保证固定帧率(通常约 60fps),但会与屏幕刷新同步,避免丢帧和卡顿。要控制节奏(比如每 100ms 执行一次逻辑),不能靠“每帧都执行”,而应记录上一次执行时间,只在达到目标间隔后才运行逻辑:
- 在 rAF 回调中接收浏览器传入的高精度时间戳(单位:毫秒)
- 用当前时间戳减去上次执行时间,判断是否达到所需间隔(如 100ms)
- 满足条件则执行动画逻辑,并更新“上次执行时间”
- 无论是否执行逻辑,都继续调用 rAF 形成循环
示例:
let lastTime = 0;<br>function animate(timestamp) {<br> if (timestamp - lastTime >= 100) { // 每 100ms 执行一次<br> // ✅ 执行你的动画逻辑(如更新位置、旋转等)<br> console.log('run at', timestamp);<br> lastTime = timestamp;<br> }<br> requestAnimationFrame(animate);<br>}<br>requestAnimationFrame(animate);避免“累积延迟”和“跳帧”问题
如果只用 lastTime += interval(即“理想时间推进”),当页面失焦或卡顿时,恢复后可能一次性触发多次,造成跳跃。更健壮的做法是:
- 始终用
timestamp - lastTime计算真实经过时间 - 允许跳过中间若干次(即只执行最新一次该做的事),而非补帧
- 对有状态的动画(如缓动),可按实际经过时间插值,而非固定步长
需要不同节奏时怎么处理
一个页面常有多个动画节奏需求(如 UI 交互动画 120fps、背景粒子 30fps)。可以封装一个简易节流控制器:
- 为每个节奏创建独立的计时器变量(如
lastUpdate_30fps) - 在统一的 rAF 循环里分别判断各节奏是否到期
- 避免为每个节奏单独开 rAF,减少开销
例如同时管理 60fps 渲染和 200ms 一次的数据轮询,共用一个 rAF 主循环即可。
注意浏览器可见性与性能影响
rAF 在标签页不可见时会自动降频甚至暂停,这是优势也是限制:
- 不需要手动监听
visibilitychange来停止 rAF(浏览器已优化) - 但若需后台持续计时(如倒计时),应改用
setTimeout或Web Worker - 移动端省电模式下 rAF 可能低于 60fps,时间戳仍可靠,逻辑无需修改
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











