requestanimationframe 更适合动画因其与屏幕刷新同步、自动暂停后台标签页且需递归驱动+退出控制;settimeout 则易不同步、不暂停且易致卡顿或资源浪费。

requestAnimationFrame 为什么比 setTimeout 更适合动画
因为浏览器会把 requestAnimationFrame 调用对齐到屏幕刷新节奏(通常是 60Hz),避免丢帧、卡顿或“撕裂”;而 setTimeout 是基于时间间隔硬调度,容易和刷新不同步,尤其在页面后台运行或 CPU 压力大时,会累积延迟或突然跳变。
更关键的是:requestAnimationFrame 在标签页不可见时自动暂停,不浪费资源;setTimeout 不会——你可能还在后台疯狂计算,但用户根本看不见。
最简可用的 requestAnimationFrame 动画结构
核心不是“启动”,而是“递归驱动 + 退出控制”。漏掉退出逻辑会导致内存泄漏和持续占用主线程。
- 必须用一个变量(如
animationId)保存上一次requestAnimationFrame的返回值 - 每次回调中先做动画更新(如修改
element.style.transform),再根据条件决定是否继续调用requestAnimationFrame - 停止动画时,必须调用
cancelAnimationFrame(animationId),否则回调会一直注册下去
let animationId = null;
const animate = () => {
// 更新位置/样式等
element.style.transform = `translateX(${x}px)`;
if (x
<h3>常见错误:直接在循环里反复调 requestAnimationFrame</h3>
<p>比如写成 <code>for (let i = 0; i —— 这会瞬间注册 100 个独立回调,全部在下一帧执行,不仅毫无渐进效果,还会阻塞渲染、触发强制同步布局。</code></p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher"><img
src="https://img.php.cn/upload/skill/000/000/081/179109368394970.jpg" alt="Wechat HTML Publisher" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="overflowclass">Wechat HTML Publisher</a>
<p class="overflowclass">直接上传HTML富文本到微信公众号草稿箱。支持完整的HTML格式,无需Markdown转换。</p>
</div>
<a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<p>真正需要的是单次注册 → 执行 → 条件判断 → 再注册(可选)。动画是“一帧一帧推进”的过程,不是“一次性批量提交”。</p>
- 不要在事件处理器(如
click)里无防护地多次调用requestAnimationFrame - 避免在
scroll或resize中直接调用,应加节流或用IntersectionObserver替代 - 如果需多元素同步动画,复用同一个
requestAnimationFrame回调,在内部遍历更新,而不是为每个元素单独注册
和 CSS 动画/transition 比,什么时候该选 requestAnimationFrame
当动画逻辑依赖运行时数据、需要逐帧干预(如跟随鼠标、物理模拟、滚动视差),或者要精确控制暂停/倒放/变速时,requestAnimationFrame 是唯一选择。CSS 的 transition 和 @keyframes 无法响应式更新缓动参数或中间状态。
但要注意:纯位移、缩放、透明度这类简单变换,优先用 CSS(开启 will-change: transform 或确保只触发合成),它走的是合成线程,不经过主线程布局与绘制,性能远高于 JS 操作 style。
混合使用也常见:用 requestAnimationFrame 计算目标值,再通过 element.animate()(Web Animations API)交由浏览器优化执行——这样既保逻辑灵活,又享底层优化。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










