js进阶教程高量级任务执行优化

当我们在页面执行渲染时候,如果这个渲染次数达到百万级别时候,界面会瞬间卡死不动

for (let i = 0; i < 10000; i++) {
    for (let j = 0 ; j < 10000; j++) {
               // console.log(i + ' ' + j)
               document.getElementById('task').innerText = i + '-' + j
           }
   }

优化点

  1. 可以延迟渲染执行(不是利用简单的setTime)
  2. 利用浏览器空闲事件去处理渲染数据
  3. 增加第一层循环次数,减少第二层循环尺寸,每次执行第一层循环次数,走延迟渲染
    具体代码如下
<!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>
    <button id="invokebtn">执行耗时任务</button>
    <span id="time"></span>
    <span id="task"></span>
    <script>

        function _runTask2(task, callback) {
            // 兼容性不好,safari不兼容
            requestIdleCallback((idle) => {
                // 判断主线程执行完,是否还有剩余时间
                if (idle.timeRemaining() > 0) {
                    task();
                    callback(); 
                } else {
                    _runTask(task, callback)
                }
            })
        }

        function _runTask(task, callback) {
            // 自己实现是否有空余时间
            let start = Date.now()
            requestAnimationFrame((idle) => {
                // 判断主线程执行完,是否还有剩余时间
                let diff = Date.now() - start
                // console.log(diff)
                if ( diff < 16.6) {
                    task();
                    callback(); 
                } else {
                    _runTask(task, callback)
                }
            })
        }
        // 执行一个任务,要求异步执行任务,返回Promise
        // 要尽快完成任务,同时不能让页面卡顿
        // 尽量兼容更多浏览器
        function runTask(task) {
            return new Promise((resolve) => {
                // 1放入微队列, 还是会堵塞
                // Promise.resolve().then(() => {
                //     task()
                //     resolve()
                // })
                
                // 2宏任务队列
                // 取出宏队列第一个任务
                // 执行任务
                // 判断是否达到渲染时间,达到了,渲染
                // setTimeout(() => {
                //     task()
                //     resolve
                // }, 0)
                
                _runTask(task, resolve)
            })
        }
        document.getElementById('invokebtn').addEventListener('click' , function () {
            for (let i = 0; i < 100000; i++) {
                runTask(() => {
                    for (let j = 0 ; j < 500; j++) {
                        // console.log(i + ' ' + j)
                        document.getElementById('task').innerText = i + '-' + j
                    }
                })
            }
        })

        let i = 0 ;
        setInterval(() => {
            document.getElementById('time').innerText = i++
        }, 10)


    </script>
</body>
</html>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值