虚拟DOM

作者: cendechen | 来源:发表于2018-05-07 17:31 被阅读0次

关于虚拟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

对上面创建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框架在如今

  1. 在牺牲一定性能的前提下,对项目的可维护性极大的增强
  2. 真正的开发模式变成了 data->view,开发人用只用关注data层的控制
  3. 让ui开发的可重用性越来越强

开发模式

view不会变化或者小范围局部变化的页面(新闻页面,宣传页面 ,H5)
直接用写html + 原生的js/jquery修改即可

view整体变化,但是性能要求不要,对重绘和回流不做严格限制
粗暴有效的方式, 一旦数据发生变化,重绘整个视图,代码构造逻辑简单

交互复杂,数据状态变化复杂
借助第三方库vue 来实现可维护性,快速开发

相关文章

网友评论

      本文标题:虚拟DOM

      本文链接:https://www.haomeiwen.com/subject/fosvrftx.html