【问题标题】:How many Reflows does attaching a DocumentFragment Cause?附加 DocumentFragment 会导致多少次回流?
【发布时间】:2013-03-21 21:43:18
【问题描述】:

使用 DocumentFramgment 允许我们将 DOM 元素彼此附加,而不会导致 browser reflow(即使用离线 DOM 树)。很多像jQuery 这样的库都使用文档片段来提高性能。

文档片段可以具有复杂的结构。例如,假设它代表如下内容:

<div>
   <span>
       <a href='asd'>asd</a>
   </span>
   <span>
       <a href='asd2'>asd2</a>
   </span>
   <div>
       <div>
          Hello World
       </div>
   </div>
</div>

或包含多个子的文档片段:

<h2>Title 1</h2>
<p>Lorem ipsum.</p>
<p>Lorem ipsum.</p>
<h2>Title 2</h2>
<p>Lorem ipsum.</p>
<p>Lorem ipsum.</p>

通常,当我们完成构建片段时,我们会将其附加到主 DOM 树。

当我们这样做时会发生多少次回流?是否取决于文档片段的直接子代数?

更新:

我收到了来自 Google Chrome 团队的 Addy Osmani 的回复:

只有一个 DOM 重排。 PS:我们更倾向于将回流称为布局,因为它基本上是在页面中触发布局/重绘的事件。

【问题讨论】:

  • 我敢打赌第一个问题的答案是“一个”
  • This 可能会有所帮助。
  • @JanDvorak 我猜所有的浏览器都只会做一次重排,但这不是实现的责任吗(即在一般情况下无法验证)?
  • @dystroy 不错的猜测。你能证明它不是规范要求的吗?

标签: javascript html reflow documentfragment


【解决方案1】:

每次调用导致一个动作的动作时,都会发生一个 DOM 重排过程。 我们可以在this article 中读到:

这种模式让我们可以创建多个元素并将它们插入到 DOM 触发单个回流。它使用一种叫做 文档片段。我们在 DOM 之外创建一个 DocumentFragment(所以 它是不合时宜的)。然后我们创建并添加多个元素 这。最后,我们将 DocumentFragment 中的所有元素移动到 DOM 但会触发一次回流。

various actions 可能会导致 DOM 回流,包括将新元素附加到文档。使用DocumentFragment 的目的是能够在单个操作中将内容附加到DOM,从而导致单个回流过程。

根据this article,我们可以读到:

有时重排文档中的单个元素可能需要 重排它的父元素以及跟随它的任何元素。

但是,所有这些回流操作都将在单个回流过程中发生。

我创建了一个fiddle 来演示这一点。使用 chrome 的时间轴,我们可以清楚地看到渲染发生在一个块中。

【讨论】:

  • 你有“导致单次回流”的来源吗?
  • 感谢您的宝贵时间和回答。然而,这更像是一个有根据的猜测而不是一个答案。 “我认为回流过程的成本可能或多或少取决于添加的内容。”如果您声称正在执行不止一次回流,您能证明吗? (来自规范,用小提琴或类似的东西)
  • 好吧,在我加入答案的文章中指出,重排单个元素可能会重排其父元素以及其后的任何元素。然而,这一切都将在一个回流过程中完成。
  • 非常好的经验过程!您能否确认这也是其他浏览器中的行为?
  • 我无法确认,但是如果您考虑一下,由于浏览器在单个线程中执行此操作,因此单个操作可能存在多个回流过程的唯一方法是它们是否允许回流使用与setTimemout 类似的方法分批运行,让一些客户端代码在批次之间执行。但是,如果执行的其他代码再次修改了 DOM 怎么办?在那种情况下,一切都必须重新计算,所以我很确定回流总是作为原子操作发生。
猜你喜欢
  • 2015-12-29
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-27
  • 2013-11-23
  • 1970-01-01
  • 2019-01-15
相关资源
最近更新 更多