rAF 比定时器更适合动画,因其由浏览器在下一次重绘前调度回调,自动暂停于页面不可见时,可优化渲染流水线,并对齐刷新节奏避免掉帧。

用 requestAnimationFrame(简称 rAF)替代 setTimeout 或 setInterval 做动画,核心在于让浏览器决定何时绘制,而不是强行“掐点”执行。它天然与屏幕刷新率同步(通常 60fps),避免丢帧、卡顿和过度渲染,是 Web 动画的推荐方式。
为什么 rAF 比定时器更适合动画
rAF 不是“每 16ms 调用一次”的机械计时器,而是由浏览器在下一次重绘前主动调度回调。这意味着:
- 当页面不可见(如切换标签页)时,rAF 自动暂停,不消耗 CPU 和电量;定时器仍运行,造成浪费
- 浏览器可合并样式计算与布局,优化渲染流水线;定时器触发时机不可控,容易打断渲染流程
- 即使主线程繁忙,rAF 也会尽量对齐刷新节奏;而
setTimeout(fn, 16)可能因排队延迟实际间隔达 30ms+,导致掉帧
如何用 rAF 实现平滑位移动画
把原来用 setInterval 递增位置的方式,改为递归调用 rAF,并根据时间差计算进度(推荐使用时间驱动,而非帧数驱动):
function animate(element, start, end, duration = 300) {
const startTime = performance.now();
<p>function step(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1); // 防止超限
const value = start + (end - start) * easeOutCubic(progress);</p><pre class="brush:php;toolbar:false;">element.style.transform = `translateX(${value}px)`;
if (progress <p>}</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java"><img
src="https://img.php.cn/upload/skill/000/000/081/178955835420587.jpg" alt="Alibabacloud Sdk Client Initialization For Java" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java" class="overflowclass">Alibabacloud Sdk Client Initialization For Java</a>
<p class="overflowclass">在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。</p>
</div>
<a rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><p>requestAnimationFrame(step);
}</p><p>// 缓动函数示例(更自然的减速效果)
function easeOutCubic(t) {
return 1 - Math.pow(1 - t, 3);
}
</p>常见误区与正确实践
直接替换定时器却不调整逻辑,反而可能出问题:
-
别在 rAF 回调里再套
setTimeout:破坏同步性,引入不确定延迟 - 避免重复启动未取消的动画:每次调用前应先 cancel 上一个 rAF ID(可用闭包或变量保存)
-
需要精确控制时,用
performance.now()算时间差,不要依赖“每帧走 1px”这种固定步长(设备性能不同,帧间隔有波动) - 复杂动画建议用 CSS transitions 或 Web Animations API:它们由合成器线程处理,比 JS 操作 DOM 更高效;rAF 更适合需要动态计算或交互响应的场景(如拖拽跟随、滚动视差)
兼容性与降级方案
现代浏览器均支持 rAF。若需兼容 IE9/10,可简单 fallback 到 setTimeout,但注意将延迟设为 16ms 并手动节流:
const rAF = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(cb) { setTimeout(cb, 16); };
<p>// 使用方式不变
requestAnimationFrame(step);
</p>
不过 IE 已退出主流支持,生产环境通常无需降级。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










