一篇文章让你了解什么是虚拟DOM

556 阅读4分钟

虚拟DOM到底是什么东西?

一句话来解释:就是一个js对象,用它来描述真实DOM

为什么说虚拟DOM的出现带来非常有变革性的改变?

先看看三部曲(从未出现虚拟DOM到虚拟DOM的出现,演变的过程) 以React为例:

一、

  • 1.state 数据

  • 2.jsx 模版

  • 3.数据 + 模版结合,生成真实的DOM,来显示页面

  • 4.state发生改变

  • 5.数据 + 模版结合,生成真实的DOM,替换原始的DOM

  • 缺陷:

  • 第一生成了完整的DOM

  • 第二次又生成了完成的DOM

  • 第二次生成的DOM替换第一次生成的DOM(非常耗费性能)

二、

  • 1.state 数据

  • 2.jsx 模版

  • 3.数据 + 模版结合,生成真实的DOM,来显示页面

  • 4.state发生改变

  • 5.数据 + 模版结合,生成真实的DOM,并不直接替换原始的DOM

  • 6.新的DOM和原始的DOM做比对,找差异(降低性能)

  • 7.找出input框发生了变化

  • 8.只用新的DOM中的input元素。替换掉老得DOM中的input元素(提高性能)

  • 缺陷:

  • 虽然相比一中替换的内容变少了,但是随之带来的是DOM的对比又降低了性能

  • 所以性能提升并不明显

三、

  • 1.state 数据

  • 2.jsx 模版

  • 3.数据 + 模版结合,生成虚拟DOM(就是一个js对象,用它来描述真实DOM)(损耗了性能,代价很小)

  • 虚拟DOM:['div',{id:'box'},['span',{},'hello world']

  • 4.用虚拟的DOM结构生成真实的DOM, 来显示页面

  • 真实DOM:<div id="box"><span>hello world</span></div>

  • 5.state发生变化

  • 6.数据 + 模版 生成新的虚拟DOM(极大提升性能,本质是生成js对象,js创建一个js对象,相比较来说损耗是极低的) 新生成的虚拟DOM:['div',{id:'box'},['span',{},'welcome to DaLian']

  • 7.比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span内容发生了改变(相比较二中的真实DOM对比,虚拟DOM(js对象对比)极大的提高性能)比较的过程就是Diff算法

  • 8.直接操作DOM,改变span中的内容

在react中从组件到真实DOM的过程:

  • jsx-> createElement-> 虚拟dom(js对象)-> 真实的DOM

虚拟DOM带来了什么好处?

  • 优点:

  • 1.性能提升了(DOM对象的比对变成了js对象的比对)

  • 2.跨端应用得以实现

虚拟DOM的diff算法(就是两个虚拟DOM在对比时候的算法)

只说diff算法的大体实现思路,具体的代码可以参考开源代码(百度上一搜都是) 在react中只有数据发生改变以后虚拟dom才会去比对,引发数据的改变只有state和props改变,其实props的改变也是父组件的state发生了改变,所以归根结底就是调用setState的时候,两个虚拟DOM做比对,有差异去更新真实的DON,在比对过程中diff算法中有一个重要的概念就是同层比较

同级比较就是,假设第一层一致再去比较第二层,假设第一层不一致这个时候不会在继续往下比较,react会把原始的虚拟DOM对应下面的所有节点DOM全部删除掉,重新生成一遍节点下的所有DOM,然后用重新生成的DOM替换原始页面伤的DOM。但是这样可能会造成性能降低,假如我第一层不相同,第二层或者第三层相同,那这样相同的也替换掉会造成资源浪费,但是这样带来的好处是算法相对来说比较简单,比对的速度随之也会加快。 为什么我们要保持key值的唯一性,这里就可以作出解答,如图:
如果每一个DOM节点没有一个key值就是没有自己的名字,当我们在做两个DOM比较的时候,节点之间的关系就很难确定,如果每一个节点都有一个唯一的key值就可以快速的建立起关联,可以极大提高性能,没加key值之前的时间复杂度是log(n* n *n) 加key值时间复杂度是log(n)

写在最后: 是一名正在成长中的web前端开发,文章写的有不完整,错误的地方,欢迎大神提出,大家共勉。