requestAnimationFrame 和 requestIdleCallback 都是浏览器提供的用于优化性能和调度的 API,但它们的用途和时机不同:
requestAnimationFrame (rAF)
作用: 在浏览器下一次重绘之前执行回调函数,专门用于动画和视觉更新。
特点:
执行时机与浏览器刷新率同步(通常是60fps,约16.7ms一次)
当页面处于非激活状态时自动暂停,节省资源
浏览器会批量处理视觉更新,减少布局抖动
使用场景:
// 动画示例
function animate() {
element.style.transform = `translateX(${position}px)`;
position += 1;
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
requestIdleCallback (rIC)
作用: 在浏览器空闲时期执行低优先级任务,避免影响关键任务。
特点:
只在浏览器空闲时执行(主线程空闲时)
可以设置超时时间,确保任务在一定时间内执行
接收 IdleDeadline 参数,告诉你还剩多少空闲时间
使用场景:
// 非关键任务,如数据上报、预加载等
requestIdleCallback((deadline) => {
while (deadline.timeRemaining() > 0 && tasks.length > 0) {
// 执行低优先级任务
performTask();
}
if (tasks.length > 0) {
requestIdleCallback(processTasks);
}
});
实际应用建议:
// 结合使用的示例
function scheduleWork() {
// 关键动画用 rAF
requestAnimationFrame(updateAnimations);
// 非关键任务用 rIC
requestIdleCallback(processBackgroundTasks, { timeout: 1000 });
}
// React Fiber 调度器中的使用
// React 使用类似机制来拆分渲染工作,避免阻塞主线程
最佳实践:
视觉更新用 rAF:保证动画流畅,避免卡顿
非关键任务用 rIC:避免影响用户交互和渲染
注意兼容性:rIC 兼容性较差,可能需要 polyfill
设置超时:对于重要但不紧急的任务,可以设置 timeout
替代方案:
对于复杂调度需求,可以考虑使用 scheduler 库
简单的延迟任务可以用 setTimeout(fn, 0),但不如 rIC 智能
这两个 API 都是现代 Web 性能优化的重要工具,合理使用可以显著提升用户体验。