天天看點

最小化重繪和重排之批量修改DOM

批量修改DOM的出發點是減少重繪和重排次數,基本思路是當需要對DOM進行多種修改操作時,首先讓DOM脫離文檔流;然後讓其進行批量修改,修改的過程不會觸發浏覽器重排和重繪;最後将修改後的DOM重新加入文檔中。這樣隻會在DOM脫離和重新加入文檔流時觸發重排和重繪操作兩次,對于批量修改這樣的操作有效降低重排和重繪次數。

DOM脫離文檔流的方法

  • 改變DOM元素的可見性:前邊的部落格已經提到隐藏的DOM節點不會出現在渲染樹。是以可以先将需要修改的元素的display屬性設為“none”,進行修改後再将其改為“block”等可見屬性值。
  • 使用cloneNode()方法:cloneNode()可以實作DOM的深拷貝(參數設定為true);是以可以将需要修改的DOM節點先進行深拷貝,對深拷貝的備份進行修改,然後用其替換原DOM節點即可。
  • 利用DocumentFragment對象:DocumentFragment對象不包含在真實的文檔流之中,是以對其修改不會觸發熱reflow和repaint。DocumentFragment對象是一個無父節點的最小化文檔對象,是一個輕量級的存儲一段包含多個節點的文檔結構。當将該對象插入DOM樹時,其通常會将其子孫節點一并插入。可以使用createDocumentFragment建立該對象,然後使用appendChild等方法插入到DOM樹。

代碼示例

//方法一: 隐藏并修改後顯示
var ele = document.getElementById('mylist');
ele.style.display = "none";
appendDataToElement(ele, data);
ele.style.display = "block";

//方法二:clone
var old = document.getElementById('mylist');
var clone = old.cloneNode(true);
appendDataToElement(clone, data);
old.parentNode.replaceChild(clone, old);

//方法三
var fragment = document.createDocumentFragment();
appendDataToElement(fragment, data);
document.getElementById('mylist').appendChild(fragment);    
           

References

  • MDN-createDocumentFragement
  • MDN-DocumentFragement Object
  • 高性能JavaScript(2015年8月第一版)

繼續閱讀