Skip to content

requestIdleCallback

requestIdleCallback 是浏览器提供的一个 低优先级任务调度 API,用于在 浏览器主线程空闲时执行回调函数,不会阻塞关键渲染和用户交互。

它的主要优势是:

  • ✅ 节省性能,不会影响页面渲染和动画流畅度
  • ✅ 适合后台任务,如日志上报、缓存预热、非阻塞计算等

🧠 参数详解

requestIdleCallback(callback) 的回调函数会接收一个 IdleDeadline 对象,它有两个主要属性:

  • deadline.timeRemaining()

    • 👉 返回本帧剩余的毫秒数(大约在 0 ~ 50ms 之间)
    • 👉 用来判断是否还有时间继续处理任务
  • deadline.didTimeout

    • 👉 如果设置了超时,判断是否是因为超时才执行回调

🔁 设置超时

你可以指定最长等待时间,如果空闲时间迟迟不来,也能强制执行:

js
requestIdleCallback(myTask, { timeout: 2000 });
html
<script>
  function sleep(duration) {
    let start = Date.now()
    while (start + duration > Date.now()) {}
  }
  let works = [
    () => {
      console.log('A1,start')
      sleep(20)
      console.log('A1,end')
    },
    () => {
      console.log('A2,start')
      sleep(20)
      console.log('A2,end')
    },
    () => {
      console.log('A3,start')
      sleep(20)
      console.log('A3,end')
    },
    () => {
      console.log('A4,start')
      sleep(20)
      console.log('A4,end')
    },
    () => {
      console.log('A5,start')
      sleep(20)
      console.log('A5,end')
    },
    () => {
      console.log('A6,start')
      sleep(20)
      console.log('A6,end')
    },
  ]
  function perforUnitOfWork() {
    let work = works.shift()
    work()
  }
  function workLoop(deadLine) {
    console.log(`本帧剩余时间${deadLine.timeRemaining()}`)
    while (deadLine.timeRemaining() > 0 && works.length > 0) {
      perforUnitOfWork()
    }
    if (works.length > 0) {
      console.log(`剩下${deadLine.timeRemaining()},时间用完下一帧执行`)
      requestIdleCallback(workLoop)
    }
  }
  requestIdleCallback(workLoop)
</script>

查看输出结果