首页 > 代码库 > js DOM优化相关探索

js DOM优化相关探索

我在这尝试两个方面:-->DOM与js

                            -->DOM与浏览器

(最近在秒味视频上学到不少,哈哈哈)

一、DOM与js

      1.js与dom的交互问题

      频繁的与dom交互,是一件浪费时间与金钱的事情,这就需要我们尽量改进自己的代码,让我们想做的事情尽量在js中做的差不多了在去跟dom打交道。 

      下面的小例子就说明了问题:

 1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta charset=utf-8> 5 <title>dom优化相关</title> 6 </head>   7 <style>   8     9 </style>  10     11 <body>12     <div id="div1"></div>13      <script>14         window.onload =  function(){15             var nDiv = document.getElementById(div1);16             var str = ‘‘;17 18             /*console.time("innerHTML10000个a所用的时间");19             //每次循环dom都与js交互,太浪费时间啦20             for(var i=0;i<10000;i++){21                 nDiv.innerHTML += a;22             }23             console.timeEnd("innerHTML10000个a所用的时间");*/24 25             console.time("获得10000个a之后innerHTML所用的时间");26             //这种就减少了js与dom的交互,大量的循环只在js中实现27             for(var i=0;i<10000;i++){28                 str += a;29             }30             nDiv.innerHTML = str;31             console.timeEnd("获得10000个a之后innerHTML所用的时间");32 33         }34     </script>35 </body>  36 </html>

(在chrome下)

这个时间的对比还是比较明显的喔。 对了,这console.time()和console.timeEnd()还挺好用的吧,其实console 还有好多亮瞎人眼的方法,可以自行google或百度脑补。

 

<------STOP  START------->:

   写到上面代码时,用到了window.onload,然后这里暂时说点别的,看下面的代码:

    

1        function t(){2             alert("1")3             }4         function b(){5             alert("2")6             }7          window.onload =t ;8          window.onload =b ;

 对吧,这只会alert(‘2‘)嘛,也就是说window.onload不能同时加载多个函数,后面的会覆盖掉前面的。

 那怎么办呢? 这有一个简单易用的方法:

 

 1  function t(){ 2             alert("1") 3             } 4   function b(){ 5             alert("2") 6             } 7    window.onload = function(){ 8             t(); 9             b();10          }

这样就可以1和2都弹窗了。

 

不过更加庆幸的是,我们还有更好的方法来为 一个事件指派多个处理程序了那就是addEventListener和attachEvent:

 1        if(window.attachEvent){ 2             window.attachEvent(‘onload‘,function(){ 3                 alert(‘ie1‘);                4             }); 5             window.attachEvent(‘onload‘,function(){ 6                 alert(‘ie2‘);                7             }); 8         }else{ 9             window.addEventListener(‘load‘,function(){10                 alert(‘1‘);11             });12             window.addEventListener(‘load‘,function(){13                 alert(‘2‘);14             });15         }

就是ie中可能执行顺序会有点不一样而已啦。

<------STOP  END------->

 

   2.在于dom交互时innerHTML与dom方法(像appendChild()这样的方法)之间的效率比较:

 1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta charset=utf-8> 5 <title>dom优化相关</title> 6 </head>   7 <style>   8     9 </style>  10     11 <body>12     <div id="div1"></div>13     <ul id="oul"></ul>14     <script>15 16         window.onload =  function(){17             var UL = document.getElementById(oul);18             var str=‘‘;19             20             21             console.time(dom操作所用时间);22             for(var i=0;i<10000;i++){23                 var LI = document.createElement(li);24                 UL.appendChild(LI);25             }26             console.timeEnd(dom操作所用时间);27 28             console.time(innerHTML操作所用时间);29             for(var i=0;i<10000;i++){30                 str += <li></li>;31             }32             UL.innerHTML = str;33             console.timeEnd(innerHTML操作所用时间);        34         }35 36 37  38     </script>39 </body>  40 </html>

下面是时间对比:

chrome:

FF:

奇异的事实证明两个浏览器下都是dom方法运行速度比较快。在我以前的认知里面两个浏览器的表现不应该是一致的,感觉ff下innerHTML应该会比dom快的。

此处也求高人指点。

 

 3.我们知道与dom相关的行为都会牵扯到时间问题,那么怎么减少dom操作呢?

    ---->使用节点克隆

  

 1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta charset=utf-8> 5 <title>dom优化相关</title> 6 </head>   7 <style>   8     9 </style>  10     11 <body>12     <div id="div1"></div>13     <ul id="oul"></ul>14     <script>15        window.onload =  function(){16             var UL = document.getElementById(oul);17             var str=‘‘;18             19            20             /*console.time(‘dom操作所用时间‘);21             for(var i=0;i<10000;i++){22                 var LI = document.createElement(‘li‘);23                 LI.innerHTML = ‘li‘;24                 UL.appendChild(LI);25             }26             console.timeEnd(‘dom操作所用时间‘);*/27 28             29             console.time(克隆节点所用时间);30             var LI = document.createElement(li);31             LI.innerHTML = li; 32             for(var i=0;i<10000;i++){33                 var newLi = LI.cloneNode(true);34                 UL.appendChild(LI);35             }36             console.timeEnd(克隆节点所用时间);37 38                    39         }40 41 42        43     </script>44 </body>  45 </html>

虽然相差不大,但是还是不一样的:

chrome:

 

  --->尽量使用局部变量

       下面两种写法也是会影响效率的,因为每次都要获取aLi.length集合也是要代价的,保存成局部变量会好些那。

          for(var i=0;i<aLi.length;i++){                aLi[i].innerHTML = ‘li‘;            }
            var  len = aLi.length;            for(var i=0;i<len;i++){                aLi[i].innerHTML = ‘li‘;            }

在上面添加10000个节点例子中尝试:

    同样的下面两种写法也是有区别的:

  

            var Div = document.getElementById();            var LI = document.getElementById();            var Input = document.getElementById();            //改成下面这样会比较好            var doc = document;            var Div = doc.getElementById();            var LI = doc.getElementById();            var Input = doc.getElementById();

 

 ---->还有就是尽量只是用获取元素节点的方法:

   

            childNodes -->元素节点、文本节点            children--> 元素节点             (利用querySelectorAll)            var oul  = document.getElementById(‘uli‘);            var ali = oul.getElementById(‘li‘);            -->            var aLi = document.querySelectorAll(‘#uli li‘);

 

二、dom与浏览器

 

    1.添加操作(尽量在appendChild前添加操作)

 1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta charset=utf-8> 5 <title>dom优化相关</title> 6 </head>   7 <style>   8    #div1 { 9      width: 100px;10      height: 100px;11      background: red;12      position: absolute;13    }14 </style>  15     16 <body>17     <div id="div1"></div>18     <ul id="oul"></ul>19     <script>20          window.onload = function(){21             var oul = document.getElementById(oul);22           23             console.time(dom操作时间);24             for(var i=0;i<10000;i++){25                 var oli = document.createElement(li);26                 //注意下面两句的位置27                 //oul.appendChild(oli);28                 //oli.innerHTML = ‘li‘;29                 oli.innerHTML = li;30                 oul.appendChild(oli);31                 32               }33             }34             console.timeEnd(dom操作时间);35          }36 37     </script>38 </body>  39 </html>

还是有一定的差别喔,可以自己动手试一下。

 

   2.合并dom操作(利用cssText)

 window.onload = function(){            var oul = document.getElementById(‘oul‘);                      console.time(‘dom操作时间‘);            for(var i=0;i<10000;i++){                var oli = document.createElement(‘li‘);                //事实上我们总以为下面第二种方法会更好些,时间会更短,但是,分别在FF和chrome中测试的话,还是有点奇妙的。(chrome中神奇的第二种更快些)                oli.style.width = ‘100px‘;                oli.style.height = ‘100px‘;                oli.style.background = ‘red‘;                //oli.style.cssText = ‘width:100px;height:100px;background:red‘;            }            console.timeEnd(‘dom操作时间‘);        }

 

  3.缓存布局信息:

window.onload = function(){            var oDiv = document.getElementById(‘div1‘);            var l = oDiv.offsetLeft;            var t = oDiv.offsetTop;            //setInterval(function(){            //    oDiv.style.left = oDiv.offsetLeft + 1 + ‘px‘;            //    oDiv.style.top = oDiv.offsetTop + 1 + ‘px‘;            //},30);            //把总是会用到的布局信息缓存起来,这样就不用总是频繁的去访问dom了            setInterval(function(){                l++;                t++;                oDiv.style.left = l + 1 + ‘px‘;                oDiv.style.top = t + 1 + ‘px‘;            },30);        }

 

 我这里一般测试时间都是在chrome下,有的ff或别的浏览器不一定会一样喔,欢迎留言一起钻研。

js DOM优化相关探索