Love.Passion.Dream

关于setTimeout在大量dom节点渲染时的优化分析

1、setTimeout传递的函数被执行的时机:

当前任何挂起的事件运行完事件句柄并且完成了文档的当前状态更新之后。

当前正在执行的JS顺序执行完毕。

简单点说:当浏览器没事干的时候。


2、用途:

setTimeout执行的时机可以看出它在性能优化方面的用途。

分割需要循环处理的数组或者过长的任务,防止过长的JS执行使得UI的更新被中断。

通过setTimeout间隔执行代码可以留出空白时间使得UI可以更新,不会产生“假死”的状态。提高用户体验。


3、实验对比:

10000个并列的dom节点进行渲染,使用Chrome的插件Monitor Tab测试出的结果如下:

未使用setTimeout


页面会停滞很久,然后突然渲染出来。耗时基本都在DOM (load)上面:



使用setTimeout

整体运行事件变长了,但是被分割成了很多块,UI不会卡死。其中最大的一块耗时其实是Time Fire

4、需要注意的坑:

IE8(其它浏览器未测试)下测试得出setTimeout过多后会莫名奇妙丢失最后一些:

setTimeout使用的间隔越小,丢失得越多。

另外不要迷恋setTimeout的时间,不会绝对精确,虽然在同一个for循环中使用相同间隔的计时器分割循环,最后执行的顺序会按照原来的顺序执行,但是通过下面这个例子可以知道setTimeout自身的定义就决定了它不适合用来通过时间做顺序控制。

console.log(0);
    setTimeout(function(){
        console.log(1111111111111);
    }, 10);
    for(var i=0; i<10000;i++){
        setTimeout(function(){
            console.log(1);
        }, 0);
    }

得出的结果是:

5、使用setTimeout做性能优化的一些原则:

1:适用与处理过程不必须同步,不必须按顺序处理的任务。

2:普遍来说,最好使用至少25毫秒的延迟,延迟过小对UI更新来说会不够。

3:不要过多的使用setTimeout,使得片段过小,定时器数量过多。


6、Web Workers

......