• 快速响应用户,让用户觉得够快,不阻塞用户的交互
    • requestIdleCallback 使开发者能够在主事件循环上执行后台和低优先级工作,而不会影响延迟关键时间,如动画、输入响应
    • 正常帧任务完成后没超过16ms,说明事件有富余,此时就会执行requestIdleCallback里注册的任务
    • requestAnimationFrame 的回调会在每一帧确定执行,属于高优先级任务,而requestIdleCallback的回调则不一定,属于低优先级任务
    1. window.requestIdleCallback(
    2. callback: (deaLine: IdleDeadline) => void
    3. option?:{timeout: number}
    4. )
    5. interface IdleDeadline{
    6. didTimeout: boolean // 表示任务执行是否超过约定时间
    7. timeRemaining(): DOMHighResTimeStamp // 任务可供执行的剩余时间
    8. }
    • callback: 回调函数就是浏览器空闲时需要执行的任务,该回调函数接受一个IdleDeadline对象作为入参,其中IdleDeadline对象包含:
      • didTimeout, 布尔值,表示任务是否超时,结合timeRemaining使用
      • timeRemaining(), 表示当前帧剩余的时间,也可理解为留给任务的时间还有多少
    • options: 目前options只有一个参数
      • timeout,表示超过这个时间后,如果任务还没执行,则强制执行,不必等待空闲时间,但是对性能会造成一定影响
    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Document</title>
    8. </head>
    9. <body>
    10. <script>
    11. function sleep(duration) {
    12. let start = Date.now();
    13. while(start + duration > Date.now()){}
    14. }
    15. function progess(){
    16. console.log('progess')
    17. requestAnimationFrame(progess)
    18. }
    19. // requestAnimationFrame(progess)
    20. // 深度遍历优先
    21. const works = [
    22. ()=>{
    23. console.log('A1开始')
    24. sleep(20)
    25. console.log('A1结束')
    26. },
    27. ()=>{
    28. console.log('B1开始')
    29. sleep(20)
    30. console.log('B1结束')
    31. },
    32. ()=>{
    33. console.log('C1开始')
    34. sleep(20)
    35. console.log('C1结束')
    36. },
    37. ()=>{
    38. console.log('C2开始')
    39. sleep(20)
    40. console.log('C2结束')
    41. },
    42. ()=>{
    43. console.log('B2开始')
    44. sleep(20)
    45. console.log('B2结束')
    46. }
    47. ]
    48. requestIdleCallback(workLoop)
    49. function workLoop(deadline){
    50. // deadline 是一个函数,返回本帧还剩余多少时间
    51. console.log(`本帧剩余时间${parseInt( deadline.timeRemaining())}ms`)
    52. while(deadline.timeRemaining() > 1 && works.length > 0){ // 本帧还有空闲时间+我还有任务没完成
    53. performUnitOfWork();
    54. }
    55. if(works.length > 0){
    56. requestIdleCallback(workLoop)
    57. }
    58. }
    59. function performUnitOfWork () {
    60. let work = works.shift()
    61. work()
    62. // works.shift()()
    63. }
    64. </script>
    65. </body>
    66. </html>