【问题标题】:When virtual-dom is faster than manual manipulation?当 virtual-dom 比手动操作更快?
【发布时间】:2015-03-27 15:46:13
【问题描述】:

我现在正在研究 virtual-dom,我想知道 virtual-dom 是否真的比手动操作视图更快。现在我明白了 virtual-dom 和 diff 算法可以防止不必要的重新流动,例如当我们想要改变这个时:

<div>
    <div>a</div>
    <div>b</div>
</div>

到这个:

<div>
    <div>c</div>
    <div>d</div>
</div>

因此,当我们使用直接操作时,我们可能会有 4 次重排:2 次用于删除每个 div 并用于创建新的。我们还将对 dom 进行更多操作,因为我们应该创建新元素(也许从 dom 中删除 -> 创建新 dom -> 设置属性 -> 安装到文档比直接编辑 dom 属性更快?)。另一方面,我们有快速漂亮的差异算法,它生成 2 个补丁来替换我们的 div 的内容,可能我们将有 1 个重流。 (如果我在写re-flows的时候写错了,请告诉我)

在这种情况下 virtual-dom 可能规则,但是当我们有 2 棵完全不同的树时,我们不会从 diff 中获得很多好处,所以我们可能会防止一些回流,但是生成新树的时间和运行差异和补丁要长得多。这是我的第二个问题。例如,在 https://github.com/Matt-Esch/virtual-dom 库的动机中,他们说:“因此,当您的应用程序状态发生变化时,无需更新 DOM,您只需创建一个虚拟树或 VTree”。每当我需要更改视图上的某些内容时,构建一个新的虚拟树真的很好吗?

当然,我会尝试做一些测试来评估性能,但我想知道更多的技术方面和为什么 virtual-dom 真的更好,或者,也许不是?

【问题讨论】:

  • 请谨慎选择您的标签。这与git 完全无关。
  • 谁说手动 DOM 操作需要替换 div?如果我关心速度,我只会为两个文本节点分配新值。
  • Bergi,这只是一个例子,我们可以拥有包含各种 DOM 项的非常深的树,我们应该能够替换 DOM 树的每个部分。我们还可以为每个 DOM 元素附加很多样式和类。

标签: javascript html dom dom-manipulation


【解决方案1】:

当您使用虚拟 DOM 时,您还需要从用户那里承担一些责任来考虑回流。

当您应用补丁时,您将它们一起应用而不读取 DOM 状态。这个时刻可以帮助您避免不必要的回流。

【讨论】:

    【解决方案2】:

    因此,当我们使用直接操作时,我们可能会进行 4 次重排:2 次用于删除每个 div 并用于创建新的。

    如果你批量处理你的 DOM 操作并且不要将它们与需要读取布局状态的操作交错(例如读取计算样式、计算偏移),那么所有这些操作一起只会导致单次回流。

    如今,浏览器的重排和重绘算法也相当先进,只调整文档的部分内容,并简单地重新合成移动的图层,如果它们不改变尺寸,则无需重绘。

    如果您担心性能,您应该使用浏览器的性能分析工具,看看究竟是什么让您变慢,以及是否可以在过早优化之前使用本机实用程序对其进行优化。

    我认为虚拟 dom 更适用于某些情况(例如服务器)发出整页 DOM 树但您只想应用差异。

    【讨论】:

    • 是的,是的,当我不交错 DOM 操作时,我将只有 1 次重流。但是为什么你认为 virtual-dom 在我们更改整页时更相关?
    • 关键是你可能会得到一个完整的 HTML blob 来替换页面,因为这是生成你的 UI 的任何东西所发出的。但即使它总是发出完整的 HTML,更改本身也很小,并且不重新注册所有 javascript 小部件、重新绘制整个页面(仅更改部分)并且不会丢失表单输入/插入符号位置等会更快。在那些情况下它很有用。
    • 是的,同意。这显然意味着我应该将我的应用程序设计为仅在某些特定情况下使用虚拟 DOM,而不是一直使用。但是即使简单地替换 DOM 树的某些部分,也可以考虑使用它,但是创建新虚拟树的逻辑应该非常快。我会尝试使用它。谢谢!
    猜你喜欢
    • 2018-12-28
    • 2011-09-04
    • 2013-11-16
    • 2020-07-29
    • 2016-06-30
    • 1970-01-01
    • 2021-05-04
    • 2020-08-02
    • 2023-03-25
    相关资源
    最近更新 更多