任务调度优先级:requestIdleCallback 与 requestAnimationFrame

1. requestAnimationFrame

requestAnimationFrame 用于实现流畅的动画。浏览器会尽可能保证在下一次重绘之前调用其注册的回调函数。

特点与优势:

  1. 同步屏幕刷新率:执行频率与设备的屏幕刷新率保持同步(通常为每秒 60 次,即 16.6ms 执行一次),不会产生跳帧或多余计算。
  2. 后台节流:当页面标签处于不可见状态或浏览器最小化时,requestAnimationFrame 会自动暂停,从而节省 CPU 资源,这比使用定时器设置固定间隔要高效得多。

2. requestIdleCallback

浏览器主线程在每帧的时间(例如 16.6ms)内,除了处理用户输入、JavaScript 执行、布局和重绘外,如果还有剩余时间,这段时间就是空闲时间。requestIdleCallback 允许开发者将非紧急的后台任务安排在这些空闲时间内执行。

参数机制: 回调函数会接收一个 deadline 对象。通过调用 deadline.timeRemaining(),可以获取当前帧还剩下多少空闲时间。开发者可以根据这个剩余时间来决定是继续执行任务还是将任务切分推迟到下一个空闲回调中。

适用场景: 处理那些不影响初次渲染和用户交互的非关键任务,例如:

  • 预先处理某些后续可能需要的数据。
  • 收集并上报非紧急的分析和统计数据。

注意事项:

  • 不能在回调中直接操作 DOM,因为此时属于帧渲染完成之后的阶段,操作 DOM 会导致不可预期的重排甚至强制同步布局。
  • 它的执行时机是不确定的,如果主线程一直很忙碌,任务可能会被较长时间推迟。传入 timeout 参数可以强制在超过指定时间后强制执行。

3. 总结对比

特性requestAnimationFramerequestIdleCallback
触发时机在下一次浏览器重绘画面之前执行在帧与帧之间的剩余空闲时间执行
优先级高,保证在每一帧按时执行低,见缝插针执行,可能会被推迟
适用场景动画渲染、高频的视觉更新计算发送统计日志、处理可切分的运算