关于requestIdleCallback

145 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情

前言

大家好,我是小阵,身为一个前端小菜鸟,总是有一个飞高飞远的梦想,因此,每点小成长,我都想要让它变得更有意义,为了自己,也为了更多值得的人

开开心心学技术大法~~

开心

来了来了,他真的来了~

正文

requestIdleCallback概述

image-20220625165612699

requestIdleCallback是推出的一个实验性质的api,旨在将低优先级任务已callback的形式存入,并在浏览器空闲时再调出执行。

语法

var handle = window.requestIdleCallback(callback[, options])

传入的callback就是浏览器空闲时执行的方法

options是可选的

可以设置timeout属性,一旦设置了该属性,倘若在timeout内执行了callback,则该属性会被忽略,如果浏览器处于繁忙时期导致callback没有在timeout时间内实现,则将该callback塞入到事件队列中,交由事件循环机制来决定何时触发

我们知道react16迎来了一波大的更新,就是因为react引入了fiber,重构了之前的数据结构,引入了fiber这种链表结构,而链表结构的一个优势就是可以很清楚的记录每条链表的状态。

能准确的记录状态,就意味着可以中断与继续。而中断和继续的时机从何处得来呢?

看到这里,应该已经可以得出结论。react fiber的优化机制也是类似的思想,不过因为是实验性质的,所以react-fiber又基于MessageChannelRestquestAnimationFrame手动实现了一个类似的方法,用于闲暇时更新fiberrender阶段,等数据全部更新完毕,再执行commit阶段,将所有更新刷在页面上。

requestIdleCallback实例

假设有多个任务

const works = [
  () => {console.log('任务1')},
  () => console.log('任务2'),
  () => console.log('任务3'),
  () => console.log('任务4'),
  () => console.log('任务5'),
]

定义一个callback

function progress(deadline) {
  console.log('还剩下多少时间', deadline, deadline.timeRemaining())
  if (deadline.timeRemaining() > 0 && works.length > 0) {
    // 如果还有空闲时间则进行任务
    let work = works.shift()
    work();
  }
  if (works.length) {
    // 如果任务还存在,则注册下一个requestIdleCallback事件
    window.requestIdleCallback(progress)
  }
}

触发requestIdleCallback

window.requestIdleCallback(progress)

查看结果

image-20220625173555426

结语

文章如有错误或不严谨之处,还望指出,感谢感谢!!!

加油!

往期好文推荐「我不推荐下,大家可能就错过了史上最牛逼vscode插件集合啦!!!(嘎嘎~)😄」