前言
这是我参与新手入门的第一篇文章。虚拟DOM,英文全称virtual dom,简称vdom,是vue和react的核心之一。vdom比较独立,使用比较简单,如果面试问到vue和react的实现,免不了要问vdom。面试肯定要问框架的原理和实现相关知识,这些都属于内功,考察面试者的基础能力、自学能力、汇总能力。了解框架的实现,在用框架的时候效率会更高,只知道用法,不知道原理,用起来遇到问题容易卡住,当然也可以求助度娘。
一、什么是vdom
vdom是用javascript模拟dom结构,不是真正的dom,但是有dom的样子。真实的dom结构如下:
<ul id="list">
<li class="item">item1</li>
<li class="item">item2</li>
</ul>
复制代码
从jquery的角度出发,我们要把item2改为item3,最直接的方案是把两个li元素删掉,然后重新插入带有item1、item3的两个li元素。
javascript模拟的dom结构如下:
{
tag:'ul',
attrs:{
id:'list'
},
children:[
{
tag:'li',
attrs:{className:'item'},
children:['item1']
},
{
tag:'li',
attrs:{className:'item'},
children:['item2']
}
]
}
复制代码
包括标签tag,属性attrs以及子节点children。有了vdom之后,我们可以把item1,item2的状态保存为一个对象,当item2变成item3的时候生成另外一个对象,第一个对象item1,item2,第二个对象item1,item3,经过js算法对比,item2变成item3。
二、为何使用vdom
用jquery删除后重新插入,还是用vdom进行对比后重新渲染,大家觉得哪种方案会比较快?
let div=document.createElement('div')
let result='';
for(let item in div){
result+='|'+item
}
console.log(result.split("|").length);//299
复制代码
上面这段代码是新建一个div元素,然后获取这个div元素属性的数量,299个属性。
大家都知道,浏览器最耗费性能的是dom操作,后一种方案更少的操作dom,很显然后一种方案会更快,现在有了v8引擎,js运行起来更快。
为什么要把dom变化的对比,放在js层来做?前端语言中html,css,js,只有js是图灵完备语言,能实现各种逻辑:如判断、循环、递归,各种数学算法,dom变化的对比是一种逻辑。dom变化,比如一个列表有3项,a,b,c,删除b,a,b,c变成了a,c,我们期望的是在a,b,c中直接删掉b,而不是把a,b,c全删掉,再把a,c插进来,后一种方式会影响性能,特别是在数据量很大的时候,项目越复杂,影响就越严重。引入vdom的目的,就是为了提高重绘性能,直接干掉b更快。