requestAnimationFrame 比定时器更高效流畅,因其与屏幕刷新率同步、自动暂停不可见页面、避免掉帧卡顿;基本用法是传入回调函数实现动画循环,配合时间戳计算进度并递归调用。

requestAnimationFrame 是浏览器提供的用于高效驱动动画的 API,它让动画与屏幕刷新率同步(通常为 60Hz),比 setTimeout 或 setInterval 更流畅、更省资源。
为什么用 requestAnimationFrame 而不是定时器?
定时器无法保证执行时机与屏幕刷新严格对齐,容易导致掉帧、卡顿或“撕裂”;而 requestAnimationFrame 由浏览器统一调度,在下一次重绘前调用回调,天然适配显示器刷新节奏。它还会在页面不可见(如切换标签页)时自动暂停,节省 CPU 和电量。
基本用法:实现一个简单动画循环
它接受一个回调函数,该函数会在下一帧执行,并传入一个高精度时间戳(DOMHighResTimeStamp),常用来计算动画进度:
let startTime = null;
const duration = 2000; // 动画持续 2 秒
<p>function animate(timestamp) {
if (!startTime) startTime = timestamp;
const progress = Math.min((timestamp - startTime) / duration, 1);</p><p>// 更新元素样式,例如平移
element.style.transform = <code>translateX(${progress * 200}px)</code>;</p><p>if (progress < 1) {
requestAnimationFrame(animate); // 继续下一帧
}
}</p><p>requestAnimationFrame(animate);</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/ai/1276" title="ARTi.PiCS"><img
src="https://img.php.cn/upload/ai_manual/001/431/639/68b6da3366e28583.jpeg" alt="ARTi.PiCS" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/ai/1276" title="ARTi.PiCS">ARTi.PiCS</a>
<p>ARTi.PiCS是一款由AI驱动的虚拟头像生产器,可以生成200多个不同风格的酷炫虚拟头像</p>
</div>
<a href="/ai/1276" title="ARTi.PiCS" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/c1c2c2ed740f" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">Java免费学习笔记(深入)</a></a>”;</p>常见实用技巧
-
取消动画:保存
requestAnimationFrame返回的 ID,用cancelAnimationFrame(id)中断循环,避免内存泄漏或意外执行 -
节流滚动/鼠标移动动画:在
scroll或mousemove中不直接操作 DOM,而是用requestAnimationFrame批量更新,防止高频触发导致性能问题 -
配合 CSS transitions / transforms 使用:优先用
transform和opacity触发硬件加速,requestAnimationFrame只负责更新这些可合成属性,效率更高 - 封装成可复用的动画工具:可基于时间戳实现 easing 缓动、暂停/恢复、回调通知等能力,避免每次手写循环逻辑
注意兼容性与降级处理
现代浏览器均支持 requestAnimationFrame,旧版 IE 需要前缀(webkitRequestAnimationFrame 等),但已基本无需考虑。若需极端兼容,可用如下简易降级:
const raf = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(callback) { return setTimeout(callback, 1000 / 60); };
<p>const caf = window.cancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
clearTimeout;</p>不过实际项目中,直接使用原生 API 即可,构建工具(如 Babel)通常不转译此 API,也不建议为它加 polyfill。









