- 快速响应用户,让用户觉得够快,不阻塞用户的交互
- 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>