requestAnimationFrame更高效因其与屏幕刷新率同步,自动节流并减少重绘。它通过系统调度在下一次重绘前执行回调,每秒约60次,避免跳帧;页面不可见时暂停,节省资源。相比setTimeout/setInterval,rAF提供精确时间戳,适合实现流畅动画。典型用法是递归调用自身,结合performance.now()计算动画进度,精准控制过渡。建议避免频繁DOM操作,优先使用transform和CSS动画,及时终止回调以防内存泄漏。合理使用rAF可显著提升动画性能与用户体验,是前端动效最佳实践。
在JavaScript中实现流畅动画时,requestAnimationFrame(简称rAF)是浏览器专为动画设计的API,相比传统的setTimeout或setInterval,它能显著提升动画性能和用户体验
。关键在于它能与屏幕刷新率同步,避免不必要的重绘,减少卡顿和掉帧。
rAF的核心优势来自其机制:它告诉浏览器“下一帧需要更新动画”,浏览器会自动在下一次重绘前调用回调函数。这个过程由系统统一调度,通常每秒60次(即60Hz),与显示器刷新率保持一致。
rAF接收一个回调函数作为参数,该函数会在重绘前被调用。通常通过递归调用自身来持续驱动动画。
function animate(currentTime) {
// 计算时间差,更新元素状态
// 例如移动小球位置
const progress = currentTime / 1000; // 单位秒
element.style.transform = `translateX(${progress * 100}px)`;
// 继续请求下一帧
requestAnimationFrame(animate);
}
// 启动动画
requestAnimationFrame(animate);
其中currentTime是DOMHighResTimeStamp,表示当前帧开始的时间,可用于实现匀速动画。
假设你想让一个元素2秒内向右平移200px。使用setInterval容易出现卡顿且难以控制精确时长。
setInterval(fn, 16)模拟60fps,可能因浏览器负载导致间隔不稳。const start = performance.now(); const duration = 2000; // 2秒 const from = 0, to = 200;function moveElement(timestamp) { const elapsed = timestamp - start; const progress = Math.min(elapsed / duration, 1); // 防止超限
const currentPos = from + (to - from) * progress; element.style.left =
${currentPos}px;if (progress < 1) { requestAnimationFrame(moveElement); } } requestAnimationFrame(moveElement);
transform而非修改top/left,利用GPU加速。@keyframes,复杂逻辑再用JS控制。基本上就这些。合理使用requestAnimationFrame,能让JavaScript动画更流畅、更节能,是现代前端动效开发的标准做法。不复杂但容易忽略细节,掌握它对性能调优至关重要。