下面的代碼說明了這個問題,改變讀/寫順序導致執行時間差異很大(使用Chrome,Firefox和IE測試):爲什麼DOM讀/寫操作的微小重新排序會導致巨大的性能差異
// read->write->read->write...
function clearSlow(divs){
Array.prototype.forEach.call(divs, function(div) {
contents.push(div.clientWidth);
div.style.width = "10px";
});
}
// read->read->...->write->write...
function clearFast(divs){
Array.prototype.forEach.call(divs, function(div) {
contents.push(div.clientWidth);
});
Array.prototype.forEach.call(divs, function(div) {
div.style.width = "10px";
});
}
下面是完整示例http://jsfiddle.net/Dq3KZ/2/的JSFiddle。
我爲n個結果= 100:
慢版:〜35MS
快速版本:〜2ms的
對於n = 1000:
慢版:〜2000毫秒
快版本:〜25ms
我認爲這與t他在每種情況下瀏覽器迴流的數量。在緩慢的情況下,每次寫操作都會發生迴流。但是,在快速情況下,迴流只會在最後發生一次。但我不確定,我不明白它爲什麼會這樣工作(當操作是獨立的時候)。
編輯:我用InnerText
屬性,而不是clientWidth
和Style.Width
,我使用谷歌瀏覽器(http://jsfiddle.net/pindexis/CW2BF/7/)時,得到了同樣的行爲。但是,使用InnerHTML
時,幾乎沒有差異(http://jsfiddle.net/pindexis/8E5Yj/)。
EDIT2:我開一個討論有關的innerHTML/innerText屬性問題,對於那些有興趣:why does replacing InnerHTML with innerText causes >15X drop in performance
因此,當請求下一個'div'的'clientWidth'時,是否改變了之前'div'的寬度,以觸發迴流? –
更改div寬度會改變回流狀態(請參閱http://www-archive.mozilla.org/newlayout/doc/reflow.html)。但是,迴流不一定要立即完成,只有在需要結果的時候。當你沒有請求寬度時,直到線程結束時纔會發生迴流(注意,你不能真正依靠這個,我記得Opera注意到如果腳本執行很長,可能會更快地發生迴流) 。由於迴流並不總是在整個頁面上,所以會發生更難以預測的事情。 –
請記住,所有這些都是依賴於實現的,但是清晰地變化並且立即在循環中讀取是一種最糟糕的情況。 –