diff算法(一)

diff算法(一)

vdom 核心价值是最大程度的减少dom渲染的范围,通过把dom用js模拟,进行计算、对比,找出最小的更新范围去更新,这个对比的过程就是diff算法。所以说diff算法是vdom中最核心、最关键的部分,能在日常使用 vue React中体现出来(比如 为什么v-for一定要用key?下面会讲到)
在这里插入图片描述
常规:树diff的时间复杂度 O(n^3)
两棵树的遍历(遍历tree1、遍历tree2、排序,1000个节点,要计算 1亿次,算法不可用)

优化:优化时间复杂度到O(n)

  1. 只比较同一层级,不跨级比较;
  2. tag不相同,则直接删掉重建,不再深度比较;
  3. tag和key,两者都相同,则认为是相同节点,不再深度比较

1、只比较同一层级

在这里插入图片描述
举个形象的例子。

<!-- 之前 -->
<div>           <!-- 层级1 -->
  <p>            <!-- 层级2 -->
    <b> aoy </b>   <!-- 层级3 -->   
    <span>diff</Span>
  </P> 
</div>

<!-- 之后 -->
<div>            <!-- 层级1 -->
  <p>             <!-- 层级2 -->
      <b> aoy </b>        <!-- 层级3 -->
  </p>
  <span>diff</Span>
</div>

我们可能期望将< span >直接移动到< p>的后边,这是最优的操作。但是实际的diff操作是移除< p >里的< span >在创建一个新的< span >插到< p >的后边。
因为新加的在层级2,旧的在层级3,属于不同层级的比较。

2、tag不同,则直接删掉重建,不再深度比较

在这里插入图片描述
如上图,D和G节点的子节点相同,但是tag不同,则重新删除重建。

3.通过key来标识区分相同节点。

开发者可以通过 key prop 来暗示哪些子元素在不同的渲染下能保持稳定。
在这里插入图片描述

左图没有key值,所以老的节点全部删除,新的节点再全部创建。右图添加key值,所以只需要将A移动到B,将C移动到D,就可以得到与新树一样的老树。

面试题:为何v-for一定需要key并且还不能是index

关于 index 作为 key 的解释。
例如,旧的 dom 结构是这样的

<ul>    
	<li key="0">张一</li>    
	<li key="1">张二</li>    
	<li key="2">张三</li>
</ul>

新的 dom 结构是这样的

<ul>    
	<li key="0">张二</li>    
	<li key="1">张一</li>    
	<li key="2">张三</li>
</ul>

这种情况,如果拿 tag 和 key 作为标准来对比,那就出错了,张二和张一就无法互换位置了。
正确的 key 应该不能拿 index ,而是用一个唯一的 id 或者标识,如:

<ul>    
	<li key="zhangyi">张一</li>    
	<li key="zhanger">张二</li>    
	<li key="zhangsan">张三</li>
</ul>

这种 key ,顺序变了也没关系。

参考
https://segmentfault.com/a/1190000008782928

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值