在没风的地方找太阳  在你冷的地方做暖阳 人事纷纷  你总太天真  往后的余生  我只要你 往后余生  风雪是你  平淡是你  清贫也是你 荣华是你  心底温柔是你  目光所致  也是你 想带你去看晴空万里  想大声告诉你我为你着迷 往事匆匆  你总会被感动  往后的余生  我只要你 往后余生  冬雪是你  春花是你  夏雨也是你 秋黄是你  四季冷暖是你  目光所致  也是你 往后余生  风雪是你  平淡是你  清贫也是你 荣华是你  心底温柔是你  目光所致  也是你
jQuery火箭图标返回顶部代码 - 站长素材

使用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>

 

 效果展示:

 

posted @ 2021-05-14 16:31  艺术诗人  阅读(237)  评论(0编辑  收藏  举报