React虚拟DOM浅析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React虚拟DOM浅析相关的知识,希望对你有一定的参考价值。

参考技术A 如果您正在使用React或学习React,那么您一定听说过“虚拟DOM”一词。现在什么是虚拟DOM?为什么React使用它?

真实DOM
首先,DOM代表“文档对象模型”。DOM用简单的语言表示应用程序的UI。每当应用程序UI的状态发生变化时,DOM都会更新以表示该变化。现在,问题是经常操纵DOM影响性能,使其变慢。

是什么导致DOM操作缓慢?
DOM表示为树数据结构。因此,DOM的更改和更新很快。但是在更改之后,必须重新渲染已更新的元素及其子元素以更新应用程序UI。UI的重新渲染或重新绘制使它变慢。因此,您拥有的UI组件越多,DOM更新的成本就越高,因为每次DOM更新都需要重新渲染它们。

那就是虚拟DOM概念出现的地方,并且其性能要比真实DOM好得多。虚拟DOM只是DOM的虚拟表示。每当我们的应用程序状态更改时,虚拟DOM就会更新,而不是真实DOM。

答案是虚拟DOM更快,更高效,这就是原因。

将新元素添加到UI时,将创建表示为树的虚拟DOM。每个元素都是该树上的一个节点。如果这些元素中任何一个的状态改变,那么将创建一个新的虚拟DOM树。然后将该树与先前的虚拟DOM树进行比较或“差异化”。

完成此操作后,虚拟DOM将计算出最佳方法以对真实DOM进行这些更改。这样可以确保对实际DOM的操作最少。因此,降低了更新实际DOM的性能成本。

下图显示了虚拟DOM树和差异化过程。

红色圆圈表示已更改的节点。这些节点表示状态已更改的UI元素。然后计算虚拟DOM树的先前版本与当前虚拟DOM树之间的差异。然后重新渲染整个父子树以提供更新的UI。然后将此更新的树批量更新为真实的DOM。

现在您对虚拟DOM是什么以及它如何对您的应用程序性能有所了解了,让我们了解一下React如何利用虚拟DOM。

在React中,每个UI块都是一个组件,每个组件都有一个状态。React遵循可观察的模式,并监听状态变化。当组件的状态改变时,React更新虚拟DOM树。虚拟DOM更新后,React然后将虚拟DOM的当前版本与虚拟DOM的先前版本进行比较。此过程称为“差异化”。

一旦React知道哪些虚拟DOM对象已更改,然后React就会在真实DOM中仅 更新那些对象。与直接操作真实DOM相比,这使性能好得多。这使React作为高性能javascript库脱颖而出。

所有这些细节都是从React开发人员那里抽象出来的。您需要做的就是在需要时更新组件的状态,React负责其余的工作。这样可以确保在使用React时获得卓越的开发人员体验。

render() 是更新和渲染UI的位置。 render() 是React中必需的生命周期方法。 render() 函数是创建React元素树的入口点。当组件中的状态或道具更新时, render() 将返回不同的React元素树。如果在组件内使用 setState() ,React会立即检测到状态更改并重新渲染组件。

然后,React找出如何有效地更新UI以匹配最新的树更改。

这是当React首先更新其虚拟DOM并仅更新实际DOM中已更改的对象时。

React遵循批处理更新机制来更新实际DOM。因此,导致性能提高。这意味着对真实DOM的更新将分批发送,而不是针对状态的每个单个更改发送更新。

UI的重新绘制是最昂贵的部分,React有效地确保了真正的DOM仅接收批量更新来重新绘制UI

React Virtual DOM Explained in Simple English

React 虚拟dom与diff算法

一、React的虚拟dom

  react生成真实dom的步骤如下:

    1、state(数据)与模版结合生成虚拟dom。

    2、React根据虚拟dom的结构生成真实dom节点(1)。

    3、数据发生改变时,生成新的虚拟dom。

    4、新的虚拟dom与原先的虚拟dom进行比较,将新的虚拟dom变动的部分替换原虚拟dom。(2)

    5、根据变动后的虚拟dom结构生成真实的dom。

    

    注解:(1)React根据虚拟dom生成真实dom,而不是直接生成真实dom。根据这个特性,可以实现跨端应用(React Native),根据虚拟dom的结构转换为原生android、ios的控件。(原生中没有dom,直接生成dom节点,不能实现跨端应用)。

         (2)React diff算法的实现。
二、React中的diff算法

  react的diff算法步骤如下:

    1、(tree diff)将react中的树形结构每一层结构进行比较,如果其中一个节点被删除,不用比较这个节点下的节点,直接重新生成真实dom (1)。

    2、(component diff)将react的树形结构中单个节点组件进行比较,如果这个组件发生改变,直接替换这个组件。

    3、(element diff)将树形结构的节点组件内部的Element元素进行比较,如果元素发生改变,替换这个元素。

    

    注解:(1)树形结构下可能n层的节点发生改变,但他下面的n+1、n+2... 层组件可能相同,这样可能会消耗性能,但算法的逻辑简单,执行快速。

 

三、React中的diff算法比较索引

    1、React是根据每一层结构上的key值进行索引比较,所以在循环时要加key值 (1)。

 

    注解:(1)循环时可能顺手就加了index作为索引,使用index做索引带来的一个后果是,当循环的数组减少一条时(不是最后一条),key值会重新赋值,原先建立的key值索引失效,不利于diff算法,所以尽量不使用index作为项目的索引。

以上是关于React虚拟DOM浅析的主要内容,如果未能解决你的问题,请参考以下文章

React虚拟DOM浅析

React虚拟DOM浅析

点评君第16期React虚拟DOM浅析

第1273期React性能优化-虚拟Dom原理浅析

React虚拟dom中的key值

React 虚拟dom与diff算法