requestIdleCallback
该函数中的回调函数将会在浏览器空闲时间被调用,即在事件循环中执行后台和低优先级工作。我们知道FPS60的电脑一帧16ms,这一帧中浏览器要做很多事情,可大概总结为以下
- 处理事件例如 click scroll change
- 定时器任务
- 执行requestAnimationFrame
- 回流重绘
- 计算更新图层绘制
- 绘制指令合并主线程 空闲时间执行requestidlecallback
然而,如果回调函数指定了执行超时时间timeout
,则有可能为了在超时前执行函数而打乱执行顺序。
另一种情况当浏览器没有任务执行会有50ms空闲时间执行requestidlecallback
react16 的fiber使用postmessage+requestAnimationFrame实现了类似于requestidlecallback,因为requestidlecallback有时候在20ms执行。
react18使用MessageChannel实现
语法
requestIdleCallback(callback, options)
-
callback
-
callback函数会接收到一个名为
IdleDeadline
的参数,这个参数可以获取当前空闲时间以及回调是否在超时时间前已经执行的状态。IdleDeadline
它的原型身上提供了一个方法,可以让你判断用户代理 (浏览器) 还剩余多少闲置时间可以用来执行耗时任务timeRemaining()
,didTimeout
(en-US), didTimeout 属性用来判断当前的回调函数是否被执行因为回调函数存在过期时间 (requestIdleCallback 的第二个参数用来指定执行超时时间,即回调函数在规定的时间内是否被执行,如果没有执行 didTimeout 属性将为 ture,如果任务是急需完成的此时应该忽略剩余时间逻辑上强制执行回调函数)。window.requestIdleCallback((idleDeadline)=>{ console.log(idleDeadline.timeRemaining()) console.log(idleDeadline.didTimeout) },{}) --》idleDeadline.timeRemaining()50 --> idleDeadline.didTimeout 是否超时还未执行 false/true
-
-
options 可选参数 -》
timeout
:如果指定了 timeout,并且有一个正值,而回调在 timeout 毫秒过后还没有被调用,那么回调任务将放入事件循环中排队,即使这样做有可能对性能产生负面影响。可能会扰乱代码的执行顺序,因此慎用
该函数返回值是一个 ID,可以把它传入 Window.cancelIdleCallback()
方法来结束回调。
使用场景
1.低优先级任务-》预加载
2.复杂-不重要的数据的处理
window.cancelIdleCallback(handle);
window.cancelIdleCallback()
方法用于取消之前window.requestIdleCallback()
的回调。
handle是调用requestIdleCallback返回的id
该方法处于试验阶段 -》兼容性不好并且由于该功能对应的标准文档可能被重新修订,所以在未来版本的浏览器中该功能的语法和行为可能随之改变。