【JS Web 前端知识库】16.说一下Diff算法?
26.说一下Diff算法?
得分点:
patch、patchVnode、updateChildren、vue优化时间复杂度为O(n)
标准回答:
Diff算法的过程
第一步:
patch函数中对新老节点进行比较 如果新节点不存在就销毁老节点 如果老节点不存在,直接创建新的节点当两个节点是相同节点的时候,进入patctVnode的过程,比较两个节点的内部
第二步:
patchVnode函数比较两个虚拟节点内部, 如果两个虚拟节点完全相同,返回 当前vnode的children不是textNode,再分成三种情况
① 有新children,没有旧children,创建新的
② 没有新children,有旧children,删除旧的
③ 新children、旧children都有,执行updateChildren比较children的差异,这里就是diff算法的核心当前vnode 的children 是textNode,直接更新text
第三步:
updateChildren函数子节点进行比较
① 第一步 头头比较。若相似,旧头新头指针后移(即oldStartIdx++&&newStartIdx++),真实dom不变,进入下一次循环;不相似,进入第二步
② 第二步 尾尾比较。若相似,旧尾新尾指针前移(即oldEndIdx--&&newEndIdx--),真实dom不变,进入下一次循环;不相似,进入第三步。
③ 第三步 头尾比较。若相似,旧头指针后移,新尾指针前移(即oldStartIdx++&&newEndIdx--),未确认dom序列中的头移到尾,进入下一次循环;不相似,进入第四步。
第四步 尾头比较。若相似,旧尾指针前移,新头指针后移(即
oldEndIdx--&&newStartIdx++),未确认dom序列中的尾移到头,进入下一次循环;不相似,进入第五步。
第五步 若节点有
key且在旧子节点数组中找到sameVnode(tag和key都一致),则将其dom移动到当前真实dom序列的头部,新头指针后移(即newStartIdx++);否则,vnode对应的dom(vnode[newStartIdx].elm)插入当前真实dom序列的头部,新头指针后移(即newStartIdx++)。
但结束循环后,有两种情况需要考虑:
① 新的字节点数组(
newCh)被遍历完(newStartIdx > newEndIdx)。那就需要把多余的旧dom(oldStartIdx -> oldEndIdx)都删除,上述例子中就是c,d;
② 新的字节点数组(oldCh)被遍历完(oldStartIdx > oldEndIdx)。那就需要把多余的新dom(newStartIdx -> newEndIdx)都添加。
💞💖💓💗每个时代,
✨🌟⭐️💫都悄悄犒赏会学习的人
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)