2014-07-22 13 views
6

考慮追加li s到一個ul這些三個版本:爲什麼追加到尚未在DOM中的元素比使用JavaScript片段更快?

樸素版(20慢%):

var ul = document.getElementById('targetUl'); 

for (var i = 0; i < 200; i++) { 
    var li = document.createElement('li'); 
    li.innerHTML = Math.random(); 
    ul.appendChild(li); 
} 

使用JavaScript片段(較慢4%):

var ul = document.getElementById('targetUl'), 
    fragment = document.createDocumentFragment(); 

for (var i = 0; i < 200; i++) { 
    var li = document.createElement('li'); 
    li.innerHTML = Math.random(); 
    fragment.appendChild(li); 
} 
ul.appendChild(fragment); 

附加到尚未在DOM中的元素(1.26%更快):

var ul = document.createElement('ul'), 
    div = document.getElementById('targetDiv'); 

for (var i = 0; i < 200; i++) { 
    var li = document.createElement('li'); 
    li.innerHTML = Math.random(); 
    ul.appendChild(li); 
} 
div.appendChild(ul); 

爲什麼追加到保存在內存中的DOM元素比追加到Fragment更快?由於fragment是爲了這個唯一目的而創建的,它不應該更快嗎?在追加內容之前,如果使用fragment而不是在頂層元素中包含頂點元素,那麼它們對於使用內存中的元素使用fragment有什麼好處?

檢查從jsperf輸出測試:http://jsperf.com/javascript-fragments-tests

+0

沒有參考底層代碼或設計,無論你得到的答案是猜測。 Mine是一個片段是任何DOM元素的通用容器,而UL是非常具體的,只能有LI子元素,所以有一個片段必須在元素被附加時做,UL不。我認爲±4%不顯着。 – RobG

+0

不要太擔心微觀優化 –

+0

什麼會使碎片更快? (假設在片段和常規DOM元素中可以做什麼優化) – JKillian

回答

7

它是更多的工作,從一個文檔片段插入多個孩子(特別是當你的試驗有200名兒童),比它是插入一個單親<ul>標籤。

因此,通過該片段,您可以將DOM片段中的200個<li>元素重新映射到您的<ul>標記中。

使用最後一個代碼塊,您只需將其中一個<ul>標記插入到DOM中即可。

因此,在您的特定示例中,使用文檔片段爲插入DOM創建了更多工作,而不像您運行最後一個只需插入單個<ul>標記的示例的方式。當你想跟蹤一大堆元素在同一水平,然後用一行代碼插入他們,你的父母已經在DOM


的片段具有其戰術優勢。但是,它並不總是最快速的方法,而不是一種方法,您可以在其實際父節點下的同一級別收集DOM中的所有項目,然後只插入該父節點。

+1

那麼爲什麼會有人想要使用文檔片段,而不是創建您打算附加到文檔的任何元素樹的父節點?是什麼讓文檔片段如此特殊,而不是僅僅創建一個父元素? – chiliNUT

+3

@chiliNUT - 有時父節點已經在DOM中,並且您想要收集DOM之外的子節點,然後一次插入它們。如果是這樣的話,那麼使用片段的代碼就會少一些,因爲不使用片段意味着您必須跟蹤一個子節點數組或創建您自己的虛擬父節點,然後必須將所有子節點單獨插入DOM 。用這個片段,你可以用一行代碼插入它們。在某些情況下,這是一種編程方便。 – jfriend00

+0

林不知道我是否理解你的答案。第二個測試比第三個測試做得更多,因爲它必須重新設置一個元素,即使該元素有很多子元素。如果我在片段中的「li」中添加了頂級元素,那麼性能會是相同的,因爲那麼它只會重新生成一個包含許多子元素的元素? – agconti

0

我的猜測是...

對於天真的版本。 在DOM中追加元素時的循環變得越來越長。 隨着更多元素被加載到DOM中存在的ul標籤中,處理後續元素所需的時間就越長。 這個需要更長的時間,因爲您正在修改DOM中已經存在的標籤。

對於Javascript片段 該片段在HTML文件中尚不存在,只在片段中插入一系列li後附加到ul中。 只有後端處理髮生在循環部分,然後將包含多重lis的片段插入到DOM中。當然,由於ul存在於DOM中,所以仍然存在一個循環,因爲需要一些時間來接收孩子。

用於附加到尚未在DOM中的元素。 這個主要在後端工作,並使得UI解釋器的工作量減少,因爲它就像在一堆論文的頂部添加另一篇論文(一切都在論文的頂部添加了論文)。

我的解釋可能不準確,但至少我是在分享一個想法。這是我們遊戲開發者最大的問題之一。

相關問題