頁面優化,DocumentFragment對象詳解

1、前言html

最近項目不是很忙,因此去看了下以前總想整理的重匯和迴流的相關資料,關於迴流優化,提到了DocumentFragment的使用,這個對象在3年前我記得是有看過的,可是一直沒深刻了解過,因此這裏作個整理。後面會把重匯,迴流也作個整理,不鴿。node

2、DocumentFragment對象是什麼?性能優化

MDN解釋:app

DocumentFragment 表示一個沒有父級文件的最小文檔對象。它被當作一個輕量版的 Document 使用,用於存儲已排好版的或還沒有打理好格式的XML片斷。最大的區別是由於DocumentFragment不是真實DOM樹的一部分,它的變化不會引發DOM樹的從新渲染的操做(reflow) ,且不會致使性能等問題。---MDNdom

W3C解釋:性能

 DocumentFragment 接口表示文檔的一部分(或一段)。更確切地說,它表示一個或多個鄰接的 Document 節點和它們的全部子孫節點。 DocumentFragment 節點不屬於文檔樹,繼承的 parentNode 屬性老是 null。 不過它有一種特殊的行爲,該行爲使得它很是有用,即當請求把一個 DocumentFragment 節點插入文檔樹時,插入的不是 DocumentFragment 自身,而是它的全部子孫節點。這使得 DocumentFragment 成了有用的佔位符,暫時存放那些一次插入文檔的節點。它還有利於實現文檔的剪切、複製和粘貼操做,尤爲是與 Range 接口一塊兒使用時更是如此。 能夠用 Document.createDocumentFragment() 方法建立新的空 DocumentFragment 節點。---W3C優化

怎麼去理解呢?咱們結合上面兩解釋能夠得知,DocumentFragment 節點不屬於DOM樹,所以它的變化不會引發DOM樹的變化;spa

咱們知道,DOM樹的操做會引發迴流,那咱們能夠將DocumentFragment做爲一個暫時的DOM節點存儲器,當咱們在DocumentFragment 修改完成時,咱們就能夠將存儲DOM節點的DocumentFragment一次性加入DOM樹,從而減小回流次數,達到性能優化的目的。code

3、DocumentFragment對象怎麼用?xml

咱們可使用document.createDocumentFragment()建立一個DocumentFragment,每一個新建的DocumentFragment都會繼承全部node方法。且DocumentFragment擁有nodeValue,nodeName,nodeType屬性。

let fragment =  document.createDocumentFragment();
console.log(fragment.nodeValue); //null
console.log(fragment.nodeName); //#document-fragment
console.log(fragment.nodeType); //11

使用DocumentFragment能解決直接操做DOM引起大量回流的問題,好比咱們要給ul添加五個li節點,區別就像這樣:

直接操做DOM,迴流五次:

使用DocumentFragment一次性添加,迴流一次:

假設咱們給ul加入五萬個li,分別對比下渲染完成時間:

html:
<body>
    <ul id="list"></ul>
    <ul id="list1"></ul>
</body>


js:
//使用documentFragment添加節點
console.time("time")
let list = document.querySelector("#list"),
    fragment = document.createDocumentFragment(),
    n = 50000;
while(n--){
  fragment.appendChild(document.createElement("li"));
};
list.appendChild(fragment);
console.timeEnd("time")

//直接操做DOM添加節點
console.time("time1")
let list1 = document.querySelector("#list1"),
    i = 50000;
while(i--){
  list1.appendChild(document.createElement("li"))
};
console.timeEnd("time1")

多刷新幾回對比二者的耗時,time是使用了DocumentFragment的耗時,time1是直接添加DOM的耗時

很明顯,time比time1耗時要短不少。

再刷新幾回試試

很明顯,屢次刷新反而還會出現使用DocumentFragment耗時更久的狀況,性能更差?打臉了。暫時沒法解釋,但願有大佬能說說。

不過讀到這,也明白了DocumentFragment是個什麼東西,怎麼使用它,那麼本文就到這裏結束了。

 

參考資料

深刻理解DOM節點類型第四篇——文檔片斷節點DocumentFragment

DocumentFragment對象

相關文章
相關標籤/搜索