js DOM優化相關探索

我在這嘗試兩個方面:-->DOM與jscss

                            -->DOM與瀏覽器html

(最近在秒味視頻上學到很多,哈哈哈)chrome

1、DOM與js瀏覽器

      1.js與dom的交互問題緩存

      頻繁的與dom交互,是一件浪費時間與金錢的事情,這就須要咱們儘可能改進本身的代碼,讓咱們想作的事情儘可能在js中作的差很少了在去跟dom打交道。 app

      下面的小例子就說明了問題: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');

 

2、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或別的瀏覽器不必定會同樣喔,歡迎留言一塊兒鑽研。

相關文章
相關標籤/搜索