虚拟DOM如何提高ReactJS的速度

How virtual DOM increases speed for ReactJS?

本文关键字:速度 ReactJS 何提高 DOM 虚拟      更新时间:2023-09-26

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

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

让我们说,如果我想添加10K节点列表,不应该需要DOM操作时间类似于ReactJS和其他框架?

每次对DOM进行增量更新或更改时,浏览器引擎都会占用更多内存和布局更改。因为它涉及到更多的几何和数学计算,这些计算是在浏览器上的每次布局变化中计算的。

然而,浏览器上的计算占用更少的内存,它不反映DOM上的任何东西。这种方法由VirtualDOM使用。

让我们以DOM为例,每个DOM都有自己的属性DOM属性,这些属性是模拟的(使用JS)。

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

所以当有一个变化时,虚拟DOM不直接反映在DOM中,而是做比较操作或差异操作,这将只返回属性或属性从以前的状态改变

所以它只会更新DOM中改变的属性。而不是为了一个小的改变而重新绘制整个DOM。

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

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

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

虚拟DOM只会改变DIV的文本,不影响子DOM的<span>和其他属性

参见

  • 浏览器如何工作浏览器如何绘制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重绘/回流比虚拟DOM要昂贵得多。

虚拟DOM在React中的工作是创建虚拟DOM树,在每个事件循环结束时,它会将当前的V-DOM树与之前的V-DOM树进行比较,然后获得补丁并操作真正的DOM。如果在一个事件循环中,用户多次修改同一个组件,React将计算最终结果并操作真正的DOM,这被称为"批处理"

所以实际上,并不是每个情况都能从react的V-DOM中获益。在你的例子中,React可能会使用innerHTML来操作真正的DOM。如果你频繁地改变其中一个元素,React会进行批处理。

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

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

这是ReactJs快速的原因之一