requestAnimationFrame与requestIdleCallback的应用及对比

52 阅读2分钟

requestAnimationFramerequestIdleCallback 都是浏览器提供的用于优化性能和调度的 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 性能优化的重要工具,合理使用可以显著提升用户体验。

在这里插入图片描述