virtual DOM 如何提高 ReactJS 的速度?

How virtual DOM increases speed for ReactJS?

我读到 ReactJS 与其他框架相比非常快,因为如果使用虚拟 dom。

我无法理解的是最终所有框架都必须在浏览器中推送 dom 对象。 virtualDom 如何帮助提高速度?

比方说,如果我想添加 10K 节点列表,ReactJS 和其他框架不需要 DOM 操作时间相似吗?

首先你必须记住 DOM 操作(重绘、回流)比 Javascript 操作昂贵得多。

例如(人为的),更新一个

  • live DOM 元素可能花费 3 秒
  • 虚拟 DOM 元素可能需要 1 秒

现在假设我有一个 DOM

<ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>

假设您想将其更新为

<ul>
    <li>First Item</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>

没有虚拟 dom 它将重新绘制屏幕上的所有 6 个元素,这将花费 3x6=18 秒

使用虚拟 dom 我们可以在内存中绘制它,这将花费我们 6 秒。绘制完成后,我们可以比较更改的内容,在我们的例子中是 1 个元素 - 我们可以在 3 秒内绘制这个元素,所以我们在 9 秒内完成了这个操作(这比没有虚拟 dom ).

当然,您可以想象并非所有情况都会受益于虚拟 dom,但在大多数情况下使用虚拟 dom 是一个显着的改进。

关键假设 是实时 DOM repaints/reflows 比虚拟 DOM.

贵很多

浏览器引擎在 DOM 上应用的每个增量更新或更改需要更多内存和布局更改。因为它涉及更多的几何和数学计算,这是在浏览器上的每个布局变化时计算的。

然而,浏览器上的计算占用的内存更少,并且不会在 DOM 上反映任何内容。 VirtualDOM 使用了这种方法。

所以让我们看一下 DOM ,每个 DOM 都有自己的属性 DOM properties,这些属性是模拟的(使用 JS)。

虚拟 DOM 保留状态假设它具有 DOM 的初始状态和所有属性

所以每当有变化时,Virtual DOM 不会直接反映在 DOM 中,而是会进行比较运算或差分运算,这只会 returns 属性或属性发生变化从以前的状态

因此它只会更新 DOM 中更改的 属性。而不是重新粉刷整个 DOM 进行微小的更改。

这在频繁更新的网络应用程序中非常有效,其中更改 DOM 的一小部分可以节省浏览器引擎的更多内存或几何计算,而不是 DOM 的整个部分。

ex: <DIV style="color:red; background-color:white;">Hello world <span>from Foo</span></DIV>

当我将文本更改为 Hello Mars 时。而不是删除并创建一个新的 DOM.

Virtual DOM 只会改变 DIV 的文本,不会影响子 <span> 和 DOM

的其他属性

另见

React 中virtual DOM 的作用是创建virtual DOM 树,并且在每个事件循环结束时,它会比较当前的V-DOM 树与之前的V-DOM树,然后拿到patch,操作真正的DOM。 如果在一个事件循环中,用户多次修改同一个组件,React 会计算最终结果并操纵真正的DOM,称为'Batching'

所以实际上,并不是每个案例都会利用反应的V-DOM。对于您的示例,React 可能会使用 innerHTML 来操作真实的 DOM。如果你经常改变其中一个元素,React 会进行批处理。

您可以参考下面的文章 http://calendar.perfplanet.com/2013/diff/

虚拟DOM是真实DOM的轻量级副本,它通过声明式API和diff算法比较那些需要修改的元素的帮助的可观察对象,然后只重绘它们。而且,尽管 virtual DOM 每次都是从头开始创建,但它只需要不到 50 毫秒,这对人类视觉感知来说并不明显。这种技术有时会加快应用程序的性能,因为它不涉及不必要数量的真实 DOM 保留其状态的“较重”元素。

这是 ReactJs is fast

的原因之一