【问题标题】:When something is appended to the DOM in memory, does that cause a browser reflow?当某些东西附加到内存中的 DOM 时,会导致浏览器重排吗?
【发布时间】:2013-02-08 22:07:01
【问题描述】:

当某些东西被附加到内存中的 DOM 时,会导致浏览器重排吗?还是只有当屏幕上的像素被告知要改变回流才会发生?例如:

案例 1: Img 元素一次一个地附加到 DOM

var parentDiv = $('#imgHolder');
var imgArray = []; // Array of img paths populated in another function

$.each(imgArray, function()
{
    parentDiv.append(createImgEle(this)); // createImgEle() // returns an <img> with the right src
}

案例 2:Img 元素被放入一个单独的数组中,然后附加到 DOM 中

var parentDiv = $('#imgHolder');
var imgArray = []; // Array of img paths populated in another function
var tempArray = []; // Holds the img elements until its fully populated

$.each(imgArray, function()
{
    tempArray.push(createImgEle(this));
}
parentDiv.append(tempArray);

案例 3: 案例 1 或 2,但默认情况下,parentDiv 设置为 display:none;,并在每个循环完成后显示。

基本上,我想知道的是,当屏幕的像素被告知改变时,浏览器是否开始回流?

顺便说一句,代码仅用于示例目的,而不是在生产中,所以不要因为任何逻辑错误而抨击我。谢谢你的建议。

【问题讨论】:

  • 在情况 1 中,每次追加都会重绘一次,而在情况 2 中,您将获得一次重绘。案例 3 我不确定。我会选择案例 2
  • 我想知道这会有什么跨浏览器差异。 IE 的处理方式与 Chrome 或 Firefox 不同吗?
  • 一般的最佳实践(基于此处和 jQuery 论坛上的众多答案以及我自己的经验)是只对 DOM 执行一次附加操作。这是否意味着一次追加一个数组,或者创建一个 DOM 片段并追加 DOM 片段的内容都无关紧要。无论哪种方式,您只接触 DOM 一次。
  • @KevinB 是的,这也是我发现的。但我只是想知道回流是否在像素被告知更改时发生。
  • 那么,回流的原因是什么?像素变化,或属性/样式/dom结构变化。我希望回流会由对 DOM 所做的更改触发,并且可能会优化为不会导致隐藏元素上的回流(未经测试,并且可能取决于浏览器)我不确定如何测试。跨度>

标签: javascript jquery performance browser


【解决方案1】:

基本上,我想知道的是,当屏幕的像素被告知改变时,浏览器是否才开始回流?

不,浏览器会在 DOM 更改时重排。之后,它会重新绘制(告诉屏幕上的像素发生变化)。

详情请看this dev.opera.com article和问题When does reflow happen in a DOM environment?

简而言之:当然还有对后续 DOM 更改的优化,例如,如果您在循环中插入一个元素数组。我不希望您的案例 1 和案例 2 有明显差异。

仅当您进行非常繁重的 DOM 更改时,您可能需要案例 #3。这使得回流(如果它们发生在插入循环期间)在遇到隐藏元素时停止,因此基本上可以防止它们。但是循环前后的两次显示变化会导致在某些浏览器中闪烁。

【讨论】:

  • +1,我喜欢你的措辞更好..事实上,在这种情况下(在现代浏览器中)真的不会有太大区别。
  • @Bergi 那篇 Opera 文章很有趣。谢谢。
猜你喜欢
  • 2011-09-29
  • 1970-01-01
  • 2012-01-14
  • 2012-09-07
  • 1970-01-01
  • 1970-01-01
  • 2012-10-19
  • 2011-07-25
  • 2010-09-30
相关资源
最近更新 更多