前言:从 60fps 的动画说起
想要实现丝滑流畅的 60fps 动画,或者在单线程 JavaScript 中实现真正的并行计算,关键在于理解事件循环的高阶应用。在 JavaScript 中,常见的动画实现方式主要有三种,它们的性能表现差异很大。
使用 setInterval(不推荐)
function animateWithSetInterval() {
setInterval(() => {
updateAnimation();
renderFrame();
}, 16.67);
}
上述代码试图达到 60fps(1000/60 ≈ 16.67ms),但定时器并不精确,容易导致丢帧或过度绘制,资源浪费严重。
递归 setTimeout
function animateWithSetTimeout() {
function loop() {
updateAnimation();
renderFrame();
setTimeout(loop, 16.67);
}
loop();
}
这种方式比 setInterval 稍好,因为它允许在每次循环前重置计时器,但仍可能和屏幕刷新不同步,造成画面撕裂。
使用 requestAnimationFrame(推荐)
function animateWithRAF() {
function loop(timestamp) {
updateAnimation(timestamp);
renderFrame();
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
}
这是目前浏览器推荐的方案。优势在于它能自动匹配屏幕刷新率,节省资源,避免不必要的渲染。
requestAnimationFrame:动画的黄金标准
什么是 requestAnimationFrame?
requestAnimationFrame(简称 rAF)是浏览器专门为动画和连续视觉更新提供的 API。它的核心特点是:在浏览器下一次重绘之前调用指定的回调函数,确保动画与屏幕刷新同步。

