关于虚拟DOM
如今流行的mvvm框架的开发模式,已经决定jquery时代将不存在,从react到vue,虚拟dom也越来越流行了,关于虚拟dom,这么高大上的名字,该怎么解读。
理解
虚拟dom,用通俗通俗易懂的话来说,就是用一个简单的JS对象去映射到dom对象, 对dom操作,都简化成对JS数据源对象的操作,页面中的每一个dom元素,都能通过这个js对象通过树的遍历算法总能找到DOM的引用地址,每一次更新数据,不需要直接去页面选取dom元素,再更新内容,而是可以直接从js对象出发找到该元素的引用,直接update
实现
简单的js对象实现
var mydiv = document.createElement('div');
document.body.append(mydiv)
这样全局就一个变量mydiv对这个div的dom的变量的引用
当然像vue和react,不可能这样来创建元素,这样也太麻烦了,简单理解和封装如下
function element(target,props,children){
var el = document.createElement(target);
for(var i in props){
el[i] = props[i];
}
//生成子树
if(children.length > 0 ){
for(var i in children){
if(typeof children[i] == "string"){
el.innerHTML = children[i];
}else{
var cel = element(children[i][0],children[i][1],children[i][2]);
el.appendChild(cel)
}
}
}
return el;
}
批量创建虚拟dom的Vnode的封装 案例
更新
想要的效果就是更新数据,直接映射到虚拟dom,虚拟dom直接映射到网页里面的真实dom
- vue的更新,diff算法 参考算法 [snabbdom] (https://github.com/snabbdom/snabbdom)
- angluar1.0 更新 digest循环
- react更新 ???
对上面创建dom的代码就行优化,我们由数据映射到真实dom。
先定义虚拟dom的数据
var velement = {
tag:'div',
props:{
className:'app'
},
children:[{
tag:'div',
props:{
className:'app-list'
},
children:['第一个列表']
},{
tag:'div',
props:{
className:'app-list'
},
children:['第二个列表']
},{
tag:'div',
props:{
className:'app-list'
},
children:['第三个列表']
}]
}
这是js对象,一个描述dom结构的数
经过vNode函数,生成一棵真实的dom树结构
image.png
我们更新velement里面的属性,我们怎么让映射到dom上呢
image.png首先需要监听数据的变化。
此处可以有两种方法
借助es6 ,object的get和set 回调函数
数据的subscriber 发布订阅者模式
再进行树的diff运算,常用的遍历树的算法有两种方法,深度优先遍历和广度优先遍历
vue用到的diff算法,采用的是深度优先遍历算法
对新旧两棵树进行一次深度优先遍历,找到每个节点都会有的唯一标记,在遍历时,每一次遍历的一个新树,如果不一样,就记录把在一个对象里面。
最后一步,根据diff结果,执行更新逻辑
性能(摘自网上,没有亲自测试)
image.png以上四幅图,以前是 原生操作,JQuery ,VirtualDOM,React,再chrome的timeline中的性能对比,再原图中,我们并没有看出虚拟dom和react 有明显的优势,原生操作是最快的,其他三种方式相差不大 。至少说明没有我们想象的那么好的性能
image.png
基于三种方式,测试插入10000个节点 100次和修改3000个节点的100次,分别取这100次的耗时最大值,最小值,和平均值,可以看出来直接原生操作更快
写在最后
其实知道了,以上原理,github上有很多实现virtualDOM的项目,可以简单读一下代码。 虚拟DOM
现在越来越流行的mvvm框架出现,主要是为解决某一类问题,或提高性能?或 提高开发效率?或提高可维护性?亦或是其他用途,往往选择一个框架是解决某一类问题,这样也会在其他方面做出牺牲。
介于虚拟dom的mvvm框架在如今
- 在牺牲一定性能的前提下,对项目的可维护性极大的增强
- 真正的开发模式变成了 data->view,开发人用只用关注data层的控制
- 让ui开发的可重用性越来越强
开发模式
view不会变化或者小范围局部变化的页面(新闻页面,宣传页面 ,H5)
直接用写html + 原生的js/jquery修改即可
view整体变化,但是性能要求不要,对重绘和回流不做严格限制
粗暴有效的方式, 一旦数据发生变化,重绘整个视图,代码构造逻辑简单
交互复杂,数据状态变化复杂
借助第三方库vue 来实现可维护性,快速开发
网友评论