我對JS的性能有疑問。使用文檔片段是否真的提高了性能?
說,我已經得到了下面的代碼:
var divContainer = document.createElement("div"); divContainer.id="container";
var divHeader = document.createElement("div"); divHeader.id="header";
var divData = document.createElement("div"); divData.id="data";
var divFooter = document.createElement("div"); divFooter.id="footer";
divContainer.appendChild(divHeader);
divContainer.appendChild(divData);
divContainer.appendChild(divFooter);
document.getElementById("someElement").appendChild(divContainer);
此代碼只是創建了一些其他功能的外殼來創建一個網格,建立網格的過程非常複雜,有許多驗證和目前我使用2種方法來填充網格,一種是在數組變量中創建整個html,另一種是創建元素並將它們附加到documentFragment
。
我的問題是,如果使用片段時性能真的有所提高,據我所知 - 它們管理內存中的元素,所以它們不會附加到文檔,因此不會觸發DOM重新計算和其他討厭的東西。但是,我創建我的變量的方式,他們沒有附加到任何DOM元素,直到我將容器追加到實際的頁面。
所以我在想,如果前面的代碼比使用包裝它的文檔片段更好的性能都喜歡這樣:
var fragment = document.createDocumentFragment();
var divContainer = document.createElement("div"); divContainer.id="container";
var divHeader = document.createElement("div"); divHeader.id="header";
var divData = document.createElement("div"); divData.id="data";
var divFooter = document.createElement("div"); divFooter.id="footer";
divContainer.appendChild(divHeader);
divContainer.appendChild(divData);
divContainer.appendChild(divFooter);
fragment.appendChild(divContainer)
document.getElementById("someElement").appendChild(fragment.cloneNode(true));
正如我已經說過,這是關於性能的一個問題,我知道作爲一個最佳實踐,建議使用片段,但我不能認爲這樣做只是在內存中創建一個新對象,並且什麼也不做,所以我認爲在這種情況下拋開片段是有效的。
希望有些js guru/god會在這裏發出一線希望,並幫助我們解決這個問題。
編輯:所以,我一直在四處尋找此問題相關的東西,它似乎documentFragments並不一定意味着更好的性能。
這只是一個「內存」容器的節點。一個片段和一個<div>
之間的區別在於該片段沒有父對象,並且它永遠不會在DOM上,只是在內存中,這意味着由於沒有對DOM進行操作,所以對片段所做的操作更快。
W3C關於documentFragments的文檔非常含糊,不過在每個人最喜歡的瀏覽器中並沒有使用真正的片段,而是根據this MSDN documentation創建了一個新文檔。這意味着,IE上的片段速度較慢。
所以,問題普遍存在,如果我創建元素(例如<div>
)在可變但不是附加IT到DOM,添加元素(div的,表格等)和東西並在所有工作完成後(循環,驗證,元素樣式),該元素被追加,它是否與片段相同?
鑑於IE使用「假」片段的事實,至少在IE中使用該方法(使用div等元素,而不是片段)更好,我真的不在乎對於IE,但我需要測試它(辦公室的政策)。
另外,如果我創建所有的HTML陣列上,像這樣:
var arrHTML = ["<table>","<tr>", ....];
,然後做這個
document.getElementById("someElement").innerHTML = arrHTML.join("");
它的方式對IE速度更快,但其他主流瀏覽器(FF,Chrome瀏覽器,Safari和Opera)在使用容器然後附加它(片段或div)時表現更好。
所有這些都是因爲創建所有元素的過程非常快速,大約需要8-10秒才能創建多達20,000行,24列,這是很多元素/標籤,但瀏覽器似乎凍結幾秒鐘之後,他們全部一起追加,如果我嘗試逐一追加它們,那就是地獄。
再次感謝人們,這真的很有趣和有趣。
將它放在jsperf上,看看目標受衆瀏覽器上哪個更快。 – jbabey
我已經在firefox和chrome中使用了控制檯的配置文件,並且它們都在同一時間(大約180ms)與頭部和數據div中的實際數據執行,我測試了沒有碎片的「香草」方式,只是將所有內容附加到cointainer和那個容器將它附加到DOM,也使用片段並在變量上創建整個html,然後向該變量添加一個innerHTML,它們似乎都工作得差不多,但我的問題是性能明智的,這是關於記憶和類似的東西更好。謝謝 –
根據我的理解,你會使用文檔片段來避免大量的重排,但如果你只是追加一小部分(比如你所展示的),那真的不值得。 – Snuffleupagus