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>