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是個什麼東西,怎麼使用它,那麼本文就到這裏結束了。
參考資料