- 快速响应用户,让用户觉得够快,不阻塞用户的交互
- requestIdleCallback 使开发者能够在主事件循环上执行后台和低优先级工作,而不会影响延迟关键时间,如动画、输入响应
- 正常帧任务完成后没超过16ms,说明事件有富余,此时就会执行requestIdleCallback里注册的任务
- requestAnimationFrame 的回调会在每一帧确定执行,属于高优先级任务,而requestIdleCallback的回调则不一定,属于低优先级任务
window.requestIdleCallback(
callback: (deaLine: IdleDeadline) => void,
option?:{timeout: number}
)
interface IdleDeadline{
didTimeout: boolean // 表示任务执行是否超过约定时间
timeRemaining(): DOMHighResTimeStamp // 任务可供执行的剩余时间
}
- callback: 回调函数就是浏览器空闲时需要执行的任务,该回调函数接受一个IdleDeadline对象作为入参,其中IdleDeadline对象包含:
- didTimeout, 布尔值,表示任务是否超时,结合timeRemaining使用
- timeRemaining(), 表示当前帧剩余的时间,也可理解为留给任务的时间还有多少
- options: 目前options只有一个参数
- timeout,表示超过这个时间后,如果任务还没执行,则强制执行,不必等待空闲时间,但是对性能会造成一定影响
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function sleep(duration) {
let start = Date.now();
while(start + duration > Date.now()){}
}
function progess(){
console.log('progess')
requestAnimationFrame(progess)
}
// requestAnimationFrame(progess)
// 深度遍历优先
const works = [
()=>{
console.log('A1开始')
sleep(20)
console.log('A1结束')
},
()=>{
console.log('B1开始')
sleep(20)
console.log('B1结束')
},
()=>{
console.log('C1开始')
sleep(20)
console.log('C1结束')
},
()=>{
console.log('C2开始')
sleep(20)
console.log('C2结束')
},
()=>{
console.log('B2开始')
sleep(20)
console.log('B2结束')
}
]
requestIdleCallback(workLoop)
function workLoop(deadline){
// deadline 是一个函数,返回本帧还剩余多少时间
console.log(`本帧剩余时间${parseInt( deadline.timeRemaining())}ms`)
while(deadline.timeRemaining() > 1 && works.length > 0){ // 本帧还有空闲时间+我还有任务没完成
performUnitOfWork();
}
if(works.length > 0){
requestIdleCallback(workLoop)
}
}
function performUnitOfWork () {
let work = works.shift()
work()
// works.shift()()
}
</script>
</body>
</html>