虚拟DOM和diff算法

Lophole 2020-07-04

     1. DOM操作非常耗费性能 
                 以前用jquery,可以自行控制DOM操作的时机,手动调整
                 Vue和React是数据驱动视图,如何有效控制DOM操作?
                2. 有了一定复杂度,想减少计算次数比较难
                 能不能把计算,更多的转移为js计算?因为js执行速度很快
                 vdom-->用js模拟DOM结构,计算出最小的变更,操作DOM
           
<div class="aaa" id="div1">
                    <p>vdom</p>
                    <ul style="font-size:20px">
                        <li>a</li>
                    </ul>
                </div>
                用js模拟DOM结构,上面的html转成下面的结构
{
                    tag:‘div‘,
                    props:{
                        className:‘aaa‘,
                        id:‘div‘
                    },
                    children:[{
                        tag:‘p‘,
                        children:‘vdom‘
                    },{
                        tag:‘ul‘,
                        props:{style:‘font-size:20px‘},
                        children:[{

                        }]
                    }]
                }
                3.通过snabbdom学习vdom
         生成vnode:h函数:传入tag元素、属性、子节点等,返回vnode数据结构return { sel, data, children, text, elm, key };
                              patch函数-->patch(vnode, newVnode),对比tag,对比tag与key,对比children
                              updateChidren==>更新children==>key的重要性
const snabbdom = window.snabbdom

// 定义 patch
const patch = snabbdom.init([
    snabbdom_class,
    snabbdom_props,
    snabbdom_style,
    snabbdom_eventlisteners
])

// 定义 h
const h = snabbdom.h

const container = document.getElementById(‘container‘)

// 生成 vnode
const vnode = h(‘ul#list‘, {}, [
    h(‘li.item‘, {}, ‘Item 1‘),
    h(‘li.item‘, {}, ‘Item 2‘)
])
patch(container, vnode)

document.getElementById(‘btn-change‘).addEventListener(‘click‘, () => {
    // 生成 newVnode
    const newVnode = h(‘ul#list‘, {}, [
        h(‘li.item‘, {}, ‘Item 1‘),
        h(‘li.item‘, {}, ‘Item B‘),
        h(‘li.item‘, {}, ‘Item 3‘)
    ])
    patch(vnode, newVnode)
})
               4. diff算法-->最大程度减少渲染的范围,通过把DOM通过js去模拟,找出最小变更和范围
                dif算法是vdom中最核心和最关键的部分
                diff算法能在日常使用vue React中体现出来(如key)
 
                5.diff算法概述
                diff即对比,是一个广泛的概念,如 linux diff,git diff
                两个js做对比
                两棵树做diff,这里的vdom diff
                6.树diff的时间复杂度 O(n^3)
                1.遍历第一棵树
                2.遍及第二棵树
                3.排序
                三次循环,1000个节点,要计算1亿次,算法不可用
                ===>
                    优化时间复杂度到O(n)
                    1.0 只比较同一层级,不跨级比较
                    2.0 tag不同,则直接删掉重建,不深度比较
                    3.0 tag和key,两者都相同,则认为是相同节点,不再深度比较
                7.diff算法源码-->生成vnode:h函数:传入tag元素、属性、子节点等,返回vnode数据结构return { sel, data, children, text, elm, key };
                              patch函数-->patch(vnode, newVnode),对比tag,对比tag与key,对比children
                              updateChidren==>更新children==>key的重要性
 
                8.vdom和diff算法总结
                   细节不重要,核心概念很重要:h,vnode,patch,diff,key
 

相关推荐