页面太卡了?试试这方法呢!
你写的代码导致浏览器运行奔溃,或页面卡住了,卡死了,怎么办? 你可以试试定时器的一个方法,叫做数组分块。
脚本长时间运行的问题通常由两个原因造成的: 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以上的时间完成,那么最好看看能否将任务分割成一系列可以使用定时器的小任务。
扫码加群,每日更新一篇前端技术文章一起成长。