Diff算法

diff算法并不是由react或者Vue或者虚拟dom提出的一个最新的概念,它是Linux的基础命令,在git代码管理工具中,在网上在线对比文件的工具中都有这个算法的应用,这个算法早就在我们身边了。在vdom中又被用来对比两个虚拟dom的节点,在vdom中应用diff算法是为了找出需要更新的节点,对比的原理和对比字符串是一样的。
在这里插入图片描述
vdom使用diff算法的原因: DOM操作是昂贵的,应尽量减少DOM的操作所以需要找出本次DOM必须更新的节点来更新,其它的不更新,找出的过程就需要用到diff算法。
从虚拟dom到真实html节点的核心流程:

  • patch(container,vnode)
  • patch(vnode,newVnode)

下面只取简单的情况,真实场景是很复杂的逻辑。
在这里插入图片描述

function createElement(vnode) {
    var tag = vnode.tag  // 'ul'
    var attrs = vnode.attrs || {}
    var children = vnode.children || []
    if (!tag) {
        return null
    }

    // 创建真实的 DOM 元素
    var elem = document.createElement(tag)
    // 属性
    var attrName
    for (attrName in attrs) {
        if (attrs.hasOwnProperty(attrName)) {
            // 给 elem 添加属性
            elem.setAttribute(attrName, attrs[attrName])
        }
    }
    // 子元素
    children.forEach(function (childVnode) {
        // 给 elem 添加子元素
        elem.appendChild(createElement(childVnode))  // 递归
    })

    // 返回真实的 DOM 元素
    return elem
}

function updateChildren(vnode, newVnode) {
    var children = vnode.children || []
    var newChildren = newVnode.children || []

    children.forEach(function (childVnode, index) {
        var newChildVnode = newChildren[index]
        if (childVnode.tag === newChildVnode.tag) {
            // 深层次对比,递归
            updateChildren(childVnode, newChildVnode)
        } else {
            // 替换
            replaceNode(childVnode, newChildVnode)
        }
    })
}

function replaceNode(vnode, newVnode) {
    var elem = vnode.elem  // 真实的 DOM 节点
    var newElem = createElement(newVnode)

    // 替换
}

还有一些复杂的情况包含:

  • 节点新增和删除;
  • 节点重新排序;
  • 节点属性、样式、事件绑定;
  • 如何极致压榨性能;

简单的了解这个算法是为了提高自己的认知能力和工作效率。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值