美文网首页
虚拟DOM和DOM diff

虚拟DOM和DOM diff

作者: Marshall3572 | 来源:发表于2021-04-05 20:27 被阅读0次

    虚拟DOM是什么?

    一个能代表DOM树的对象,通常含有标签名、标签上的属性、事件监听和子元素们,以及其他属性。

    虚拟DOM的优点:

    DOM每发生一次改变,浏览器都会进行一次完整的渲染(重排与重绘),有了虚拟DOM之后,DOM发生改变时先修改对应虚拟DOM,虚拟DOM的改变并不会直接渲染,而是等所有改变完成之后进行渲染,避免不必要的操作从而提高性能。

    1. 减少不必要的DOM操作(下边这两个例子要背下来)。
    • 虚拟DOM可以将多次操作合并为一次操作,减少DOM操作的次数。(比如你添加1000个节点却是一个接一个操作的)
    • 虚拟DOM借助DOM diff算法可以把多余的操作省掉,减少DOM操作的范围(比如你添加1000个节点,其实只有10个是新增的)。
    1. 跨平台渲染:
      由于虚拟dom是个对象,所以可以跨平台并支持服务端渲染。

    虚拟DOM长什么样子?

    // Vue
    const vDode = {
        tag: "div", //标签名 or 组件名
        data: {
            class: "red", // 标签上的属性
            on: {
                click: () => {} // 事件
            }
        },
        children: [
            {tag: "span", ...},
            {tag: "span", ...}
        ],
        ...
    }
    

    如何创建一个虚拟DOM

    // ReactcreateElement
    createElement('div', {className: 'red' , onClick:() => {}},[
        createElement('span', {}, 'span1'),
        createElement('span', {}, 'span2')
    ])
    // Vue(只能在render函数里得到h)
    h('div', {
        class: 'red',
        on: {
            click: () => {}
        },
    }, [h('span', {}, 'span1'), h('span', {}, 'span2')])
    

    改进(用JSX简化创建虚拟DOM)

    // React 通过babel 转为 createElement 形式
    <div className="red" onClick = {fn}>
        <span>span1</span>
        <span>span2</span>
    </div>
    // Vue 通过vue-loader转换为 h 形式
    <div class="red" @click="fn">
        <span>span1<span>
        <span>span2<span>
    </div>
    

    虚拟DOM的缺点

    当首次渲染大量DOM或者全部DOM,因为多了一层虚拟DOM的计算,反而比直接渲染慢
    需要额外的创建函数,比如createElement(React)或h(Vue),但可以通过JSX来简化成XML写法。

    DOM diff

    什么是DOM diff?
    DOM diff就是比较两个虚拟DOM之间有什么差异的算法
    DOM diff就是一个函数,我们称之为patch
    patches = patch(oldVNode, newVNode)
    patches 就是我们要运行的DOM操作。
    DOM diff的大概逻辑
    将新旧两棵树逐层对比,找出哪些节点需要更新。
    如果节点是组件就看Component diff,如果检点是标签就看Element diff
    Component diff
    如果节点是组件,就看组件类型,类型不同直接替换(删除旧的),类型相同就只更新属性,然后深入组件做Tree diff(递归)
    Element diff
    如果节点是原生标签,则看标签名,标签名不同直接替换,相同则只更新属性。然后进入标签后代做Tree diff(递归)。
    DOM diff的优点
    对比新旧节点,查找出差异并只修改差异部分,极大提高性能。
    DOM diff的问题(key)
    当虚拟DOM没有唯一标识符(key)时,默认以索引作为标识,那么两个相同的节点由于索引不同依然会进行修改删除等操作。

    相关文章

      网友评论

          本文标题:虚拟DOM和DOM diff

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