vue的虚拟DOM和diff算法,是Vue面试的最后一招
一、什么是虚拟DOM
通过js创建一个Object对象来模拟真实DOM结构,这个对象包含标签名 (tag)、属性 (attrs) 和子元素对象 (children) 三个属性,通过vue中的render()函数把虚拟dom编译成真实dom,在通过appendChild()添加到页面中。
再来一张图:
是不是一下子秒懂 没懂再来一张
创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应
在vue中如何应用虚拟DOM的
定义真实DOM
<div id="app">
<p class="p">节点内容</p>
<h3>{
{ foo }}</h3>
</div>
实例化vue
const app = new Vue({
el:"#app",
data:{
foo:"foo"
}
})
vue源码中render函数渲染虚拟DOM
(function anonymous() {
with(this){return _c('div',{attrs:{"id":"app"}},[_c('p',{staticClass:"p"},
[_v("节点内容")]),_v(" "),_c('h3',[_v(_s(foo))])])}})
通过
VNode
,vue可以对这颗抽象树进行创建节点,删除节点以及修改节点的操作,经过diff算法得出一些需要修改的最小单位,再更新视图,减少了dom操作,提高了性能
二、为什么需要虚拟DOM
DOM是很慢的,其元素非常庞大,页面的性能问题,大部分都是由DOM操作引起的
真实的DOM节点,哪怕一个最简单的div也包含着很多属性,可以打印出来直观感受一下:
由此可见,操作DOM的代价仍旧是昂贵的,频繁操作还是会出现页面卡顿,影响用户的体验
举个例子:
你用传统的原生api或jQuery去操作DOM时,浏览器会从构建DOM树开始从头到尾执行一遍流程
当你在一次操作时,需要更新10个DOM节点,浏览器没这么智能,收到第一个更新DOM请求后,并不知道