zoukankan      html  css  js  c++  java
  • 使用requestIdleCallback实现一帧执行多任务,

    概念:

    为什么是16.67毫秒:

    这个根据浏览器刷新帧率来定,大多数浏览器的刷新帧率是60Hz,所以1/60 = 0.0166666... (秒)= 16.67(毫秒)

    如果一个任务耗时很长,那么时间用完后会中断该任务吗?

      不会中断该任务,一直到执行完毕为止,所以如果单个任务耗时很长,那么也会造成卡顿。

    测试用例:

    <!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></title>
    </head>
    <body>
        
    </body>
    <script>
        function sleep(delay) {
            //在js里面实现睡眠功能
            for (let start = Date.now(); Date.now() - start <= delay;) {}
        }
    
        //fiber 是把整个任务分成很多个小任务,每次执行一个任务
        //执行完成后会看看有没有剩余时间,如果有继续执行下一个任务,如果没有就放弃执行,使用requestIdleCallback将控制权交还给浏览器
        let requesqQueut = [
            () => {
                console.log('第一个任务开始')
                sleep(20)//一帧16.67毫秒(1000/60帧),所以需要把控制权交给浏览器
                console.log('第一个任务结束')
            },
            () => {
                console.log('第二个任务开始')
                sleep(20)
                console.log('第二个任务结束')
            },
            () => {
                console.log('第三个任务开始')
                sleep(20)
                console.log('第三个任务结束')
            },
            () => {
                console.log('第四个任务开始')
                sleep(20)
                console.log('第四个任务结束')
            },
        ]
    
        //告诉浏览器1000毫秒后,即使你没有空闲时间,也得帮我执行,因为我已经等不及了
        window.requestIdleCallback(callBack, {timeOut: 1000})
        //deadLine是一个对象,有两个属性
        //timeRemaining() 返回此帧执行剩余时间
        //didTimeout 此callBack是否超时
        function callBack(deadLine) {
            console.log(`本帧的剩余时间为:${deadLine.timeRemaining()}`)
            //如果此帧=还有剩余时间 或 此时已经超时了
            while ((deadLine.timeRemaining() > 0 || deadLine.didTimeout) && requesqQueut.length > 0) {
                performUnitOfQueueTask()
            }
            
            //说明还有没有执行完的任务
            if (requesqQueut.length > 0) {
                window.requestIdleCallback(callBack, {timeout: 1000})
            }
        }
    
        function performUnitOfQueueTask() {
            requesqQueut.shift()()
        }
    </script>
    </html>

     

     效果展示:

  • 相关阅读:
    工作感悟(一)
    laydate组件选择时间段的判断
    Win10下免安装版JDK8环境变量配置
    IDEA中lombok插件的安装
    解决加载WEB页面时,由于JS文件引用过多影响页面打开速度的问题
    Windows环境下的MYSQL5.7配置文件定位
    MYSQL使用source命令,导入SQL文件
    MYSQL5.7生成列简介及创建
    MYSQL慢查询优化方法及优化原则
    批量提取文件夹下所有目录及文件名称
  • 原文地址:https://www.cnblogs.com/art-poet/p/14769073.html
Copyright © 2011-2022 走看看