页面太卡了?试试这方法呢!

你写的代码导致浏览器运行奔溃,或页面卡住了,卡死了,怎么办? 你可以试试定时器的一个方法,叫做数组分块。

脚本长时间运行的问题通常由两个原因造成的: 1.过长或过深的函数调用 2.进行大量处理的循环。

长时间循环通常遵循下面模式
for(let i = 0,len = data.length; i < len; i ++) {
    process(data[i])
}

这个模式的问题在于 要处理的项目的数量在运行前是不可知的,如果要完成process()要花100ms,两个项目的数组可能不会造成影响,但是10个的数组可能要1秒钟,数组中的项目数量直接关系到完成循环的时间长度,由于js的执行是一个阻塞操作,脚本运行所花的时间越久,用户无法与页面交互时间越久。

在循环前有两个问题,

  • 1.该处理是否必须同步完成?(如果这个数据的处理,会造成其他运行的阻塞,那么最好不要动它)
  • 2.数据是否必须按顺序完成?(通常数组只是对项目的组合和迭代的一种简单的方法而无所谓顺序,如果项目顺序不是那么重要,那么可以将某些处理推迟到以后)

当你发现某个循环占用了大量的时间,同时对上述两个问题答案都是否,那么你可以使用定时器分割这个循环。这个技术交数组分块

要实现数组分块非常简单,下面这函数拿去用

function chunk(array,process,context) {
    setTimeout(function(){
        //取出下一个条目并处理
        var item = array.shift();
        process(item);
        
        //若还有条目再使用另外一个计时器
        if(array.length > 0) {
            setTimeout(arguments.callee,100)
        }
    },100)
}

chunk()方法接受三个参数,要处理的项目的数组,用于处理项目的函数,以及可选的运行该函数的环境

比如把一个数组中的每个值输出到每一个div元素。

let data = [12,3,21,3,21,312,3,453,123,1232];
function printValue(item) {
    let div = document.getElementById("myDiv");
    div.innerHTML += item + '<br/>'
}
chunk(data,printValue)



由于shift改变数组条目了,所以可以把数组克隆一下,在传递给chunk 如:

chunk(data.concat(),printValue)

今后,一旦有某个函数要花50ms以上的时间完成,那么最好看看能否将任务分割成一系列可以使用定时器的小任务。

扫码加群,每日更新一篇前端技术文章一起成长。

原文地址:https://www.cnblogs.com/bbqq1314/p/12545441.html