了解react中的虚拟DOM

在我学习vue框架的时候,就时常听到虚拟DOM的概念,后来了解到vue2.0新增了虚拟DOM,那时我并不知道这会有什么意义,因为我只想关心怎么使用框架。时至今日,我在学习react,在网上浏览react相关文章的时候,虚拟DOM这一词汇也是被时常提及,可能是因为react框架是使用虚拟DOM的先行者吧。于是我就花了一些时间,简单地了解了一下,如果不去追究代码的实现,我也可以简单说说我的理解。

为什么需要虚拟DOM?

可能本来我应该先说说什么是虚拟DOM,但这其实没啥可说的,我们就可以把它定义为js对象,但真要说起来可能也有很多东西可以说,关于这个网上已有一大堆好文,我就不去照搬了。我就想说说为啥需要虚拟DOM?其实很多像我这样的人可能不了解虚拟DOM,但是我们却知道它可以提高性能,那么它到底是怎么提高性能呢?

设计一个框架

在这里,我不写代码,我们来假设一下,如果我们自己来实现一个react框架,那么我们会怎么来实现?好吧,我们先借鉴一下react框架,来理个思路:

  1. state(数据层),本着不直接操作DOM而是操作数据的原则,我们会有一个数据存放的地方;
  2. jsx(模板),模板最终会生成DOM结构用于展示,其实jsx语法实现的内容就相当于模板;
  3. 数据 + 模板 结合,生成DOM结构,用于显示;
  4. state数据发生变化;
  5. 数据 + 模板 结合,生成新的DOM结构,并替换掉原先的DOM结构。

按照上面这五个步骤去设计我们的框架,这完全是没有大问题的。功能是可以实现了,但缺点也是很明显的,很多时候页面只会变化一小部分,如果每次变化都要重新渲染整个DOM结构,这显然大大消耗了性能。要知道我们在使用js时都是尽量避免直接操作DOM的,所以我们需要尝试改进。

改进框架

我们知道上面步骤中需要改进的地方就是最后一步,我们不应该在数据变化时替换掉整个DOM结构,而是替换需要更改的地方,于是我们可以按如下步骤实现:

  1. state(数据层),本着不直接操作DOM而是操作数据的原则,我们会有一个数据存放的地方;
  2. jsx(模板),模板最终会生成DOM结构用于展示,其实jsx语法实现的内容就相当于模板;
  3. 数据 + 模板 结合,生成DOM结构,用于显示;
  4. state数据发生变化;
  5. 数据 + 模板 结合,生成新的DOM结构,不直接替换原先的DOM结构;
  6. 新的DOM和原始DOM作对比,找出差异部分;
  7. 找到差异的部分后,只替换需要变化的DOM结构;

上面的步骤,前四步还和以前一样,到了第五步时,我们先不直接替换整个DOM,而是在接下来比较新旧DOM,找到需要变更的地方,然后实现部分更新替换。现在,我们解决了这个整体替换DOM结构的大隐患,实现了局部更新,这听起来似乎性能嗖嗖的上去了。然鹅~聪明的你一定发现了,这里面有一个步骤似乎并不讨喜,那就是第六步,新旧DOM做对比。对比啥?是在对比DOM结构啊!这也是相当消耗性能的。搞了半天,其实性能并没有提升多少,说不定还下降了。所以,我们还需要改进!

虚拟DOM的引入

吁~终于扯到虚拟DOM上了,没错,接下来我们就加入虚拟DOM的概念来改进我们的框架。还记得我上面开始说的嘛,虚拟DOM你可以理解为就是一个js对象,不过这个对象里保存了DOM信息,我们一步一步看。

首先,前两步我们总是需要的:

  1. state(数据层);
  2. jsx(模板);

接下来,我们要结合数据和模板,但是这次我们先不直接生成DOM结构,而是生成虚拟DOM:

  1. 数据 + 模板 生成虚拟DOM (虚拟DOM是js对象,用来描述真实DOM信息),如:

    1
    2
    3
    ['div',{id:'root'},['span',{},'hello world']]

    //上面对象所描述的信息就是:<div id="root"> <span>hello world</span> </div>
  2. 用虚拟DOM结构生成真实的DOM结构,来显示,即

    1
    <div id="root"> <span>hello world</span> </div>
  3. state发生变化;

  4. 数据 + 模板 生成新的虚拟DOM,如:

    1
    2
    3
    ['div',{id:'root'},['span',{},'hi']]

    //hello world 变成 hi
  5. 比较原始虚拟DOM和新的虚拟DOM,区别就是span中内容的变更;

  6. 直接改变DOM中span中的内容。

看到这,我想你对虚拟DOM有了大概的了解了。查看上面步骤,你可能也会疑问,生成虚拟DOM这里不会消耗性能吗?其实肯定会消耗一些性能的,但相比较直接生成真实DOM结构,肯定是大大降低消耗的,而且后面的对比差异就是直接对比js对象,不涉及DOM操作,这里也是大大提升了效率的。

以上就是我对虚拟DOM的简单理解,一些地方可能说的不太对,但我的意思应该是明显的吧,嘿嘿~

最近在忙找新工作的事,其实也不忙。虽然收到几个offer,但不是自己喜欢的,哎,大家还是对应届生的能力有所怀疑啊,我表示无力,只能说我能力还是不足啊。多学学,继续加油。