虚拟dom是什么?「前端每日一题v22.11.14」
虚拟dom这个词大家都不陌生,对于习惯使用框架的我们来说,Vue和React当中都有对于虚拟dom的使用和说明。经常会有面试官问你,虚拟dom是什么,有什么优势,为什么会存在虚拟dom
虚拟dom实际是真实dom的映射,真实的dom就是平时存在于浏览器当中的dom节点。虚拟dom本质来说是一个js对象,包含了type(组件还是元素)style,class,children,data等,树的形式不断延伸
在虚拟dom出现之前,我们是如何更新我们的页面的呢?在jquery那个年代,更新dom的操作基本上就是替换,把旧的dom替换成更新后的dom,基本上就完成了交互,但是这个过程也比较繁琐,比如我们必须要先找到对应的dom,然后写新的dom,然后再替换
人们就在想有没有什么好的方式,就是只要我们的数据变化了,那dom自然就变化了,答案是肯定的,那就是后面出现的模版引擎,学过服务端的同学对模版引擎有所了解,模版引擎开了个好头,让我们只关注于数据的变化,但是模版引擎并没有dom的对比操作,比如我想渲染一个列表,那模版引擎就会替换整个列表,不管是不是列表当中就一个字段发生变换
「这种操作无疑是非常耗费性能的」
于是,就有大神们想要优化这种操作,如何优化,就是想要在更新dom这个环节
对比一下模版引擎和虚拟dom的更新区别
「模板引擎:数据 + 模板 --> 直接渲染为真实 DOM --> 挂载至页面」
「虚拟dom:数据 + 模板 --> 虚拟DOM --> 真实DOM --> 挂载至页面」
既然操作大量的dom非常消耗性能,那我们就操作少量的dom就可以了,如何减少操作呢?就是在操作dom之前,我们先对比一下到底哪些dom需要更新,而不是全量更新,减少dom操作,新旧虚拟dom做一个diff操作,只更新想要的
但是仅仅这样就会变快么?其实不然,因为中间多了dom对比的操作,有可能这个对比操作也会比较耗性能,就会导致本质并不会快多少,所以虚拟dom一定会比dom直接操作快是错误的说法,只能说有可能,或者说分场景,比如在一个巨大的列表下,你只是更新了一个字段,那虚拟dom肯定胜出。如果在一个简单的dom下,那模版引擎少了dom diff,就会更快一些
那为什么还要虚拟dom呢?其实还有一个重要的点,虚拟dom是一层抽象的描绘,那就表明这一层是可以用在多端,这是极为重要的一点
那虚拟dom中是如何做对应的描述的?对应的js对象是一个什么样的内容?
const vnode = {
type: 'div',
props: {
id: 'hello'
},
children: [
/* 更多 vnode */
]
}
这里借用vue中的虚拟dom的节点说明,上面描述的是一个div节点,它还可以包含更多的节点,放在children中,运行框架的时候,框架会遍历整个虚拟dom节点,以此来建立真实的dom树,可以将这个过程称为挂载,挂载完成之后,新旧dom对比,将发生变化的节点进行更新,这个过程可以称为diff,或者更新
整个过程如下
这就是整个虚拟dom相关内容,整体来看,虚拟dom的利远远大于弊端,这使得它在大型框架面前称为标配,对于工具的学习不能仅仅只是停留在表面,还要尽量了解它的发展历程,形成一种工具思维