JavaScript DOM的本質及操作方法

 在Web開發中,JavaScript的一個很重要的作用就是對DOM進行操作,可你知道麼?對DOM的操作是非常昂貴的,因爲這會導致瀏覽器執行迴流操作,而執行了過多的迴流操作,你就會發現自己的網站變得越來越慢了,我們應該儘可能的減少DOM操作。本文將給出了一些指導性原則,比如在什麼時候應該對DOM可以進行什麼樣的操作等。

     

    我們都知道,DOM操作的效率是很低的,而且不是一般的慢,而且這也是引發性能問題的常見問題之一。爲什麼會慢呢?因爲對DOM的修改爲影響網頁的用戶界面,重繪頁面是一項昂貴的操作。太多的DOM操作會導致一系列的重繪操作,爲了確保執行結果的準確性,所有的修改操作是按順序同步執行的。我們稱這個過程叫做迴流(reflow),同時這也是最昂貴的瀏覽器操作之一。迴流操作主要會發生在幾種情況下:

    ◆當對DOM節點執行新增或者刪除操作時。

    ◆動態設置一個樣式時(比如element.style.width="10px")。

    ◆當獲取一個必須經過計算的尺寸值時,比如訪問offsetWidth、clientHeight或者其他需要經過計算的CSS值(在兼容DOM的瀏覽器中,可以通過getComputedStyle函數獲取;在IE中,可以通過currentStyle屬性獲取)。
    解決問題的關鍵,就是限制通過DOM操作所引發迴流的次數。大部分瀏覽器都不會在JavaScript的執行過程中更新DOM。相應的,這些瀏覽器將對對DOM的操作放進一個隊列,並在JavaScript腳本執行完畢以後按順序一次執行完畢。也就是說,在JavaScript執行的過程中,用戶不能和瀏覽器進行互動,直到一個迴流操作被執行。( 失控腳本對話框 會觸發迴流操作,因爲他執行了一箇中止JavaScript執行的操作,此時會對用戶界面進行更新)

    如果要減少由於DOM修改帶來的迴流操作,有兩個基本的方法。第一個就是在對當前DOM進行操作之前,儘可能多的做一些準備工作。一個經典的例子就是向document對象中添加很多DOM節點:

  1. for (var i=0; i < items.length; i++){  
  2.     var item = document.createElement("li");  
  3.     item.appendChild(document.createTextNode("Option " + i);  
  4.     list.appendChild(item);  
  5. }  

這段代碼的效率是很低的,因爲他在每次循環中都會修改當前DOM結構。爲了提高性能,我們需要將這個次數降到最低,對於這個案例來說,最好的辦法是建立一個文檔碎片(document fragment),作爲那些已創建元素元素的臨時容器,最後一次將容器的內容直接添加到父節點中:

  1. var fragment = document.createDocumentFragment();  
  2. for (var i=0; i < items.length; i++){  
  3.     var item = document.createElement("li");  
  4.     item.appendChild(document.createTextNode("Option " + i);  
  5.     fragment.appendChild(item);  
  6. }  
  7. list.appendChild(fragment); 

經過調整的代碼,只會修改一次當前DOM的結構,就在最後一行,而在這之前,我們用文檔碎片來保存那些中間結果。因爲文檔碎片沒有任何可見內容,所以這類修改不會觸發迴流操作。實際上,文檔碎片也不能被添加到DOM中,我們需要將它作爲參數傳給appendChild函數,而實際上添加的不是文檔碎片本身,而是它下面的所有子元素。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章