Ami*_*sef 13 javascript performance firefox dom google-chrome
以下代码说明了问题,更改读/写顺序会导致执行时间的巨大差异(使用Chrome,Firefox和IE测试):
// 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";
});
}
Run Code Online (Sandbox Code Playgroud)
这是一个完整的例子http://jsfiddle.net/Dq3KZ/2/的JSFiddle .
我的结果为n = 100:
慢版本:~35ms
快速版本:~2ms
对于n = 1000:
慢速版本:~2000ms
快速版本:~25ms
我认为这与每种情况下浏览器重排的数量有关.在慢速场景中,每次写入操作都会发生回流.但是,在快速场景中,回流仅在结束时发生一次.但我不确定,我不明白它为什么会这样工作(当操作独立时).
编辑:我使用了InnerText属性而不是clientWidth和Style.Width,在使用谷歌浏览器时我有相同的行为(http://jsfiddle.net/pindexis/CW2BF/7/).但是,当InnerHTML使用时,几乎没有差异(http://jsfiddle.net/pindexis/8E5Yj/).
Edit2:我已经为那些感兴趣的人开启了关于innerHTML/innerText问题的讨论:为什么用innerText替换InnerHTML导致性能下降> 15X
这些行动不是独立的.
当样式或内容大小发生变化并且需要位置或尺寸时,必须进行重排,因为您要求维度或因为必须更新屏幕(代码完成时).
div.clientWidth是一个隐藏的函数调用.当您请求此值时,您实际上请求了一个最新值,因此,当样式更改时,您会触发立即重排.
在"快速"情况下,在重新绘制屏幕或请求大小之前,没有理由进行重排.在这种情况下,实际上只需要一次回流.