理解React的虚拟DOM

一、背景

        React是一个用于构建用户界面的JavaScript库,区别于老的前端开发技术,其最核心的就是引入了虚拟DOM的技术。为了对React有一个比较全面和深入的了解,所以把最近学习React虚拟DOM的知识,做个笔记,仅供学习。

二、什么是虚拟DOM

        那什么是虚拟DOM呢?官方解析是,Virtual DOM是一种编程概念。通俗点理解,虚拟DOM是一棵虚拟的JavaScript对象树,画重点,”虚拟的“、”JS对象“,指的是它把真实的网页文档节点,虚拟成一个个的js对象,并以树型结构,保存在内存中。

三、虚拟DOM的实现原理

        React虚拟DOM的实现原理,通过JS模拟网页文档节点,生成JS对象树(虚拟DOM),然后再进一步生成真实的DOM树,再绘制到屏幕。如果后面有内容发生改变,React会重新生成一棵全新的虚拟DOM树,再与前面的虚拟DOM树进行比对diff,把差异的部分打包成patch,再应用到真实DOM,然后渲染到屏幕浏览器。

理解React的虚拟DOM_第1张图片

Virtual DOM具体步骤可具体表现为:

1、构建虚拟DOM

var tree = el('div', {class:'main'}, [
    el('span', ['hello,world'])
])

2、通过虚拟DOM构建真正的DOM

var root = tree.render()
document.body.appendChild(root)

3、内容更改,生成新的虚拟DOM

var newTree = el('div', {class:'main'}, [
    el('span', ['hello, 张三'])
])

4、比较1和3两棵虚拟DOM树,得到patch

var patches = diff(tree, newTree)

5、把patch应用到真正的DOM上

patch(root, patches)

另外,针对第4点,有必要深入了解一下diff算法,虚拟dom是如何做diff比较的。从三个比较来看:tree diff 、component diff 和 element diff。

a、tree diff

      Web UI中DOM节点跨层级的移动操作特别少,可以忽略不计。即,1与1层比较,2与2层比较....,如果相同层,对应的节点不存在了,则该节点及其所有子节点会被全部删除掉,这样的好处是降低树形遍历的复杂度。

理解React的虚拟DOM_第2张图片

如果还是出现了DOM节点的跨层级的移动操作,那就出现下图这样的。

理解React的虚拟DOM_第3张图片

A节点及其子节点B、C被移动到D节点下面,但注意,右边的A、B、C并不就是左边直接移动过来的,准确来说,是根据原来的A、B、C节点重新创建的。因为React为了降低树形结构遍历的复杂度,只对同层级的节点进行移动,对于不同级别的节点是,先创建,后删除。所以上图的操作过程应该是:右边A节点创建->右边B节点创建->右边C节点创建,最后把左边A节点及其所有子节点(B和C)全部删除。

b、component diff

理解React的虚拟DOM_第4张图片

 相同类的两个组件,生成相似的树形结构;不同类的两个组件,生成不同的树形结构。这话怎么理解?当比对到A节点的时候,发现它们是同类的组件,所以会接着后面的结构元素比较。如果是不同类的组件,压根就不考虑其两个的内部结构是怎样,如D节点和G节点,直接对其删除,并重新创建G及其所有子节点。

c、element diff

对于同一层级的一组子节点,通过唯一ID(key)区分

理解React的虚拟DOM_第5张图片

diff 通过插入、移动和删除对节点进行操作,根据key的标识,A、B、C、D 四个元素节点都是原来的节点,唯一的区别就是A节点的位置改变了,所以按真实DOM最少操作的原则,B/C/D三个节点不做任何变化,移动A节点即可。

四、React虚拟DOM与Jquery操作真正DOM,性能优在哪?

       在学习的过程中,一直有个疑问,虚拟DOM的这种技术真的比Jquery性能会优吗?React发生更改还总是生成新的虚拟DOM树,最终也是需要去更新真实的DOM的呀,为什么呢?

1、虚拟DOM的节点元素相对比较简单,真实DOM的节点要复杂得多。

2、虚拟DOM的操作和真实DOM的操作是两个引擎,相互独立。

3、虚拟DOM在内存中操作,其实速度是非常快的,所以他们的瓶颈在于JS引擎与真实DOM引擎通信和DOM引擎的绘制上。

4、虚拟DOM通过diff算法,计算更改的部分,从而降低了真实DOM的操作节点。

5、增加缓冲区,等全部计算好后,再将缓冲区的数据一次性复制到显示缓冲区,这样的图形输出也比较稳定。Jquery以及传统的做法,频繁的调用DOM API,操作真实的DOM,引起页面的重绘,开销会变得非常昂贵。

       但是,如果我们改动的部分很小,与真实DOM引擎的通信内容和次数一样,相反,虚拟DOM更像是个累赘,多余的。不过,React这种前端技术,要解决的问题,不仅仅如此,是从整体和综合性思考的,对于复杂的系统,让开发者更关注数据和视图的变化,把复杂的真实DOM操作包装掩盖起来,是一种前端开发模式的革命。

五、React虚拟DOM与Vue虚拟DOM的差别?

        react函数式组件思想,在发生数据(setState)更改后,会重新生成新的虚拟dom树,然后进行新旧虚拟dom树的diff(自顶向下的全量diff)

        vue是组件响应思想,采用代理监听(watcher)数据,当一个组件内数据更改,可以明确知道并响应这个组件进行diff比较(局部订阅)

你可能感兴趣的:(web前端,react.js,javascript,前端,vue,dom)