requestIdleCallback
在浏览器的事件循环(Event Loop)中,空闲阶段(Idle Phase) 执行。 它会在浏览器完成其他高优先级任务(例如处理用户输入、渲染页面、执行 JavaScript 等)后,并且有剩余时间时才会被调用。
执行方式:
-
注册回调函数: 使用
requestIdleCallback(callback, options)
注册一个回调函数callback
。options
可选,用于设置超时时间。 -
空闲阶段调用: 浏览器在完成一个事件循环的 tasks、microtasks 队列后,如果还有剩余时间,就会进入空闲阶段。这时,它会检查是否有通过
requestIdleCallback
注册的回调函数。 -
执行回调函数: 如果有待执行的回调函数,浏览器会依次执行它们。 回调函数会接收一个
IdleDeadline
对象作为参数。 -
IdleDeadline
对象: 这个对象提供了两个重要的属性:timeRemaining()
: 返回当前帧剩余的空闲时间。didTimeout
: 指示回调函数是否因为超时而被执行。如果options
中设置了timeout
,并且在timeout
时间内回调函数没有被执行,则didTimeout
为true
。
-
分片执行: 为了避免阻塞主线程,建议在回调函数中执行少量的工作,并在需要继续执行时再次调用
requestIdleCallback
进行下一轮的处理。 可以通过timeRemaining()
判断剩余时间,如果时间不足,则停止当前工作,等待下一帧的空闲时间再次执行。
示例:
function myIdleCallback(deadline) {
while (deadline.timeRemaining() > 0) {
// 执行一些任务,例如处理数据、更新 UI 等
console.log('Time remaining:', deadline.timeRemaining());
// ...
if (/* 任务完成 */) {
break; // 退出循环
}
}
if (/* 还有任务需要执行 */) {
requestIdleCallback(myIdleCallback); // 再次注册回调函数
}
}
requestIdleCallback(myIdleCallback);
总结:
requestIdleCallback
提供了一种机制,允许开发者在浏览器空闲时执行低优先级的任务,例如:
- 数据预加载
- 延迟渲染
- 计算密集型任务的拆分执行
通过合理利用 requestIdleCallback
,可以提高网页的性能和用户体验,避免阻塞主线程,保证页面的流畅性。
需要注意的是,requestIdleCallback
的兼容性不如其他 API 那么好,在使用时需要考虑兼容性问题,或者使用 polyfill。 而且,由于它是在空闲时间执行,所以不能保证回调函数一定会被执行,或者执行的时机。 对于一些对实时性要求较高的任务,不建议使用 requestIdleCallback
。