我知道有两个理由认为React的Virtual DOM更快-
我对这两点都有疑问-
请您参考如下方法:
我找到了我问题的答案。
关键是要了解虚拟DOM的目的。
首先,我们必须看到React使用什么方法来渲染组件。
不同的javascript框架采用不同的方法来检测数据模型中的更改并将其呈现在 View 上。
考虑AngularJS。当我们在Angular模板中(例如在类似{{foo.x}}的表达式中)引用数据时,Angular不仅会渲染该数据,还会为该特定值创建一个监视程序。每当我们的应用程序中发生任何事情(单击事件,HTTP响应,超时)时,所有观察程序都将运行。如果观察者中的值已更改,则该值将在UI中重新呈现。通过运行所有观察程序,AngularJS实质上可以确定需要在哪里进行更改。运行这些观察程序的过程称为脏检查。
React采用了不同的方法。每当React组件中发生状态更改时,React无需找出更改的位置(例如AngularJS),而是从头开始重新渲染整个UI(具有更新的状态)。
但是React的这种方法有一个问题。重新渲染整个UI意味着重新渲染整个DOM树。这是一个问题,因为DOM更新是一个缓慢的过程(由于重排和重绘)。
这就是React的虚拟DOM出现的地方。虚拟DOM只是以JavaScript对象形式表示真实DOM的一种表示形式。它只是内存中存在的纯JavaScript对象的树型数据结构。与真实DOM相比,虚拟DOM的呈现要快得多,因为它从未在屏幕上呈现(无需进行重排或重新绘制)。
那么虚拟DOM如何解决该问题呢?当我们加载应用程序时,React创建一个虚拟DOM,它是真实DOM的精确虚拟副本。只要组件中的状态发生变化,React便会渲染整个新的Virtual DOM(具有更新的状态),而不是重新渲染整个Real DOM。然后,它会在旧的虚拟DOM(真实DOM的初始副本)与新的虚拟DOM(状态更改后呈现)之间进行区分,以找出它们之间的变化,并且仅在真实DOM中进行这些更改。这样,可以重新渲染整个UI(通过渲染整个新的Virtual DOM),但是在Real DOM中仅进行了最小限度的更改。
因此,当说“使用Virtual DOM React仅更新那些需要更新的元素”(我的问题中的第1点)时,这意味着在Virtual DOM React的帮助下,它克服了其自身方法的局限性(从头开始渲染整个用户界面)。
此answer也解释了相同的概念。
我已经看到一些答案,指出使用React进行DOM操作比使用DOM api更快,因为DOM api重新呈现了整个DOM树,而React仅重新呈现了需要更改的DOM树的那些部分。这不是真的。所有现代浏览器的效率都足以更新DOM树中那些需要更改的部分。可以使用浏览器的开发人员工具中的绘画闪烁来验证这一点(另请参见answer和answer)。即使我们假设DOM api确实重新渲染了整个DOM树,该推理仍然是错误的,因为React本身的内部代码必须使用DOM api来更新DOM。如果DOM api确实重新渲染了整个DOM树,那么React也会重新渲染整个DOM树,因为最终它也使用DOM api来更新DOM。
关于第二点,React实际上使我们更容易进行批处理。
在React中,虽然读取是在Real DOM上完成的,但是写入(状态更改)却没有在Real DOM上完成。而是将写入排队。然后,当我们所有的读写操作都已完成后,便会基于该写操作构建一个新的虚拟DOM。然后在新旧虚拟DOM之间进行区分,然后React将所需的更改写入到真实DOM进行更新。因此,最终所有对Real DOM的写操作都在一次重排中一起完成。
但是,我们也可以在没有React的情况下手动编写代码,这样,首先完成所有读取,然后完成所有写入。 React使批处理变得容易,因为有了React,我们不必在意读写操作,React会自动为我们批处理写操作。因此,React不会使事情变得很快。它使事情变得容易。
总而言之,我们可以说React实际上并不快。更容易。正如Pete Hunt在video中所说:“反应不是魔术。就像您可以使用C进入汇编程序并击败C编译器一样,您也可以进入原始DOM操作和DOM API调用,并在需要时击败React。但是,使用C或Java或JavaScript可以将性能提高一个数量级,因为您不必担心...平台的细节。使用React,您甚至无需考虑性能即可构建应用程序,并且默认状态很快。” 。
Rich Harris的这首post也指出“虚拟DOM快速”是一个神话。






