探究React虚拟DOM

Posted 2bit潮学

tags:

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

关注 入坑互联网 ,回复“加群




什么是虚拟DOM

React将DOM抽象为虚拟DOM, 然后通过新旧虚拟DOM 这两个对象的差异(Diff算法),最终只把变化的部分重新渲染,提高渲染效率的过程;

为什么使用虚拟DOM

在传统的 Web 应用中,我们往往会把数据的变化实时地更新到用户界面中,于是每次数据的微小变动都会引起 DOM 树的重新渲染。

虚拟DOM的目的是将所有操作累加起来,统计计算出所有的变化后,统一更新一次DOM。

为什么虚拟DOM会比DOM更优

当创建一个元素比如div,这个元素上本身或者继承很多属性如 width、height、offsetHeight、style、title,另外还需要注册这个元素的诸多方法,比如onfucos、onclick等等。这还只是一个元素,如果元素比较多的时候,还涉及到嵌套,那么元素的属性和方法等等就会很多,效率很低。

这个元素会挂载默认的styles、得到这个元素的computed属性、注册相应的Event Listener、DOM Breakpoints以及大量的properties,这些属性、方法的注册肯定是需要h耗费大量时间的。

尤其是在js操作DOM的过程中,不仅有dom本身的繁重,js的操作也需要浪费时间,我们认为js和DOM之间有一座桥,如果你频繁的在桥两边走动,显然效率是很低的。

React的虚拟DOM就是解决这个问题的!虽然它解决不了DOM自身的繁重,但是虚拟DOM可以对javascript操作DOM这一部分内容进行优化。

来看下面这个最简单的例子,你就明白了:

比如说,现在你有一个列表是这样:

<ul> <li>0</li> <li>1</li> <li>2</li> <li>3</li></ul>

你希望变成下面这样:

<ul> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li></ul>

通常先把0, 1,2,3这些Element删掉,然后加几个新的Element 6,7,8,9,10进去,这里面就有4次Element删除,5次Element添加。共计9次DOM操作。

那React的虚拟DOM可以怎么做呢?

而React会把这两个做一下Diff,然后发现其实不用删除0,1,2,3,而是可以直接改innerhtml,然后只需要添加一个Element(10)就行了,这样就是4次innerHTML操作加1个Element添加。共计5此操作,这样效率的提升是非常可观的。

虚拟DOM和DOM之间的关系

首先,Virtual DOM并没有完全实现DOM,即虚拟DOM和真正地DOM是不一样的,Virtual DOM最主要的还是保留了Element之间的层次关系和一些基本属性。因为真实DOM实在是太复杂,一个空的Element都复杂得能让你崩溃,并且几乎所有内容我根本不关心好吗。所以Virtual DOM里每一个Element实际上只有几个属性,即最重要的,最为有用的,并且没有那么多乱七八糟的引用,比如一些注册的属性和函数啊,这些都是默认的,创建虚拟DOM进行diff的过程中大家都一致,是不需要进行比对的。所以哪怕是直接把Virtual DOM删了,根据新传进来的数据重新创建一个新的Virtual DOM出来都非常非常非常快。(每一个component的render函数就是在做这个事情,给新的virtual dom提供input)。

所以,引入了Virtual DOM之后,React是这么干的:你给我一个数据,我根据这个数据生成一个全新的Virtual DOM,然后跟我上一次生成的Virtual DOM去 diff,得到一个Patch,然后把这个Patch打到浏览器的DOM上去。完事。并且这里的patch显然不是完整的虚拟DOM,而是新的虚拟DOM和上一次的虚拟DOM经过diff后的差异化的部分。

虚拟DOM是怎么工作的?

与真实DOM相似,虚拟DOM也是节点树,以对象的形式列出内容,属性。React的render方法从React组建中创建节点树,因为动作改变等引起数据模型变化的时候,React更新节点树。

每次React app内部的数据改变,用户界面的虚拟DOM都会构建。

这里就是最有趣的地方,在React中更新浏览器DOM需要三步:

  1. 每次数据模型变化的时候,虚拟DOM节点树都会重新构建。

  2. React依赖某个算法(称之为diff算法)来与上一个虚拟DOM节点数进行比较,只有在不同的情况下才重新进行计算。

3.所有的变化要经过批处理,完成之后,真实DOM才进行更新。

过程如下图:探究React虚拟DOM

虚拟DOM慢吗?

有人认为只要有一点改变就重新构造整个虚拟DOM节点树有点浪费,但是他没有提及一个事实,React在内存中存储有两个虚拟DOM树。

但是,真实情况是渲染虚拟DOM总是比直接渲染浏览器DOM快。这种论断与你使用的浏览器也没多大的关系。

最后,我们来说一下为什么Virtual Dom快

由于每次生成virtual dom很快,diff生成patch也比较快,而在对DOM进行patch的时候,虽然DOM的变更比较慢,但是React能够根据Patch的内容,优化一部分DOM操作.

重点就在最后,哪怕是我生成了virtual dom(需要耗费时间),哪怕是我跑了diff(还需要花时间),但是我根据patch简化了那些DOM操作省下来的时间依然很可观(这个就是时间差的问题了,即节省下来的时间 > 生成 virtual dom的时间 + diff时间)。所以总体上来说,还是比较快。



探究React虚拟DOM

 相关推荐







探究React虚拟DOM

点在看的人特别帅/美




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

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

Vue源码探究-虚拟DOM的渲染

关于React中的虚拟DOM与Diff算法

Web技术858- 增量 DOM 与虚拟 DOM 的对比使用

2.ReactJS基础(虚拟DOM,JSX语法)

虚拟DOM,到底快在哪