requestanimationframe(raf)既不是宏任务也不是微任务,它在event loop中拥有独立调度时机,位于本轮宏任务末尾、微任务之后、渲染之前,由浏览器按帧率主动触发并批量执行。

requestAnimationFrame(raf)既不是宏任务,也不是微任务,它在Event Loop中拥有独立的调度时机——位于本轮宏任务末尾、下一轮宏任务开始前,且优先级高于宏任务但低于微任务。
raf 的执行时机:独立于宏/微任务队列
浏览器规范中,raf 回调被归入“Animation Frame Tasks”,属于一个特殊的任务类别。它的触发不依赖于宏任务队列(如 setTimeout、I/O)或微任务队列(如 Promise.then、MutationObserver),而由浏览器根据屏幕刷新节奏(通常每 16.6ms 一次,即 60fps)主动调度:
- 当一帧开始时(即浏览器准备重绘前),会检查是否注册了 raf 回调;
- 若存在,则在该帧的渲染前、所有微任务执行完毕后,立即批量执行所有待处理的 raf 回调;
- 执行完 raf 后,才进行样式计算、布局、绘制等渲染操作。
执行顺序:微任务 → raf → 渲染 → 下一轮宏任务
在一个完整的事件循环周期中,典型执行顺序如下:
- 执行当前宏任务(如 click 处理函数);
- 执行该宏任务产生的所有微任务(Promise.then、queueMicrotask 等);
- 执行已注册的 raf 回调(如果当前帧尚未执行过 raf);
- 进行页面渲染(Layout → Paint);
- 从宏任务队列中取出下一个宏任务执行。
注意:raf 不会“插队”到微任务中间,也不会被推迟到下一帧——只要在当前帧内被 request,就一定在本次渲染前执行(除非被取消或浏览器处于后台)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
与 setTimeout(0) 和 Promise.then 的对比
以下代码可直观体现调度差异:
console.log('1');
setTimeout(() => console.log('2'), 0); // 宏任务
Promise.resolve().then(() => console.log('3')); // 微任务
requestAnimationFrame(() => console.log('4')); // 动画帧任务
console.log('5');
// 输出顺序通常是:1 → 5 → 3 → 4 → 2
解释:
- '1' 和 '5' 是同步代码;
- '3' 在本轮微任务队列执行;
- '4' 在微任务之后、渲染之前执行;
- '2' 被推入下一轮宏任务队列,要等渲染完成才执行。
实际开发中的关键注意事项
使用 raf 时需注意:
- raf 回调只在浏览器处于前台且页面可见时才会被调度(标签页不可见时可能暂停或降频);
- 同一帧内多次调用 requestAnimationFrame,只会保留最后一次注册的回调(浏览器自动去重);
- raf 不是“更轻量的 setTimeout”,而是专为动画设计的机制,应配合 CSS 动画、transform 等硬件加速属性使用;
- 若需精确控制帧节奏(如游戏循环),建议用 raf + performance.now() 计算时间差,而非依赖固定间隔。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










