认识 vdom

330 阅读2分钟

dom

前端对 dom 太熟悉不过了,如下:

<div class="one">
    <div class="two">
        <a href="#">hello</a>
    </div>
    <p style="font-size: 20px;">world</p>
</div>

vdom

那什么是 vdom 呢? vdom 就是用 js 描述的 dom。比如上面的 dom 可以用下面的 js 对象描述。

{
    // tag 表示的节点的名字, 是 div 节点害死 a,p 等节点
    tag: 'div',
    // props 表示节点上的属性
    props: {
        // className 表示 class, 因为 class 是关键词,行业通用写法, className === class
        className: 'one'  
    },
    // children 表示有孩子节点,如果孩子几点是文本,就直接 text 属性表示
    children: [
        {
            tag: 'div',
            props: {
                className: 'two',
            },
            children: [
                {
                    tag: 'a',
                    props: {
                        href: '#'
                    },
                    // a 节点里面的子节点是文本,故用 text 直接表示, 不用 children 
                    text: 'hello'                    
                }
            ]
        },
        {
            tag: 'p',
            props: {
                style: 'font-size: 20px;'
            },
            text: 'word'
        }
    ]
}

为什么有 vdom

vdom 首先是由 react 项目里面提出来的。在 react 之前,前端开发者都是用 Jquery 或者原生 js 直接操作 dom。操作 dom 是很耗时间和性能的,因为修改 dom 的后,游览器需要重新 回流重绘,频繁的修改 dom,游览器所需要的开销很大,所以直接操作 dom 很慢。但是执行 js 却很快的。如果把 dom 操作放到 js 中去执行,再一次性去渲染到 dom 中,那必然快很多。所以 vdom 出现了。结合 diff 算法比对,最小化更新原生 dom 操作。所以现在 react vue 里面都用到了 vdom

举一个简单的栗子

for(var i=0; i<10; i++) {
    var div = document.createElement('div');
    div.innerHTML = i;
    document.getElementById('app').appendChild(div)
}

上面代码表示获取页面中一个 idappdiv,并往里面添加了 10 个新的 divfor 循环第一遍的时候,appendChild div 节点到页面中。游览器发现 dom 有改变,会立马重新渲染页面,发生 回流和重绘。游览器是不知道你后面还有第 2 次,第 3 次到。所以就一遍一遍的重新渲染,很耗性能,效率很低。

如果把创建 div 放到 vdom 里面操作,最后再 appendChild 到页面中,游览器只渲染了一次。是不是效率高很多呢。

总结

vdom 是基础面试中经常会问到的问题,面试官可能会给你一段 dom 结构,让你用 js 来描述这个 dom。所以参考上面的 vdomjs 描述。做到自己能用 js 手写描述 vdom