React 之reconciliation--diff算法

本文深入探讨了React的diff算法,对比传统diff算法的O(n^3)复杂度,React采用的O(n)算法基于类型差异和key属性,高效更新DOM。文章通过实例展示了不同DOM元素、相同组件及children的变化如何影响React的渲染过程,强调了key在优化性能中的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考文档https://reactjs.org/docs/reconciliation.html
传统的diff算法https://grfia.dlsi.ua.es/ml/algorithms/references/editsurvey_bille.pdf。为了用最少的操作,把一颗树结构转化成另外一颗树结构,使用了非常复杂的算法,复杂度达到了O(n^3),其中n为树的节点数。

与传统的diff算法相比,React使用的是一种复杂度为O(n)的diff算法,基于两点基本的假设:

1.Two elements of different types will produce different trees.
2.The developer can hint at which child elements may be stable across different renders with a key prop.

不同类型的DOM元素

	<div>
		<ComponentA />
	</div>
----------------------------------
    <span>
		<ComponentA />
	</span>

由于div和span是不同类型的DOM元素,React将重新渲染,原来的树结构将会被销毁,ComponentA也将被卸载,componentWillUnmount会被调用。新的ComponentA生成后,componentWillMount和componentDidMount将会被调用。

相同类型的DOM元素

	<div className="class1">aaaa</div>
-------------------------------------------	
	<div className="class2">aaaa</div>

React不会销毁原来的DOM元素,仅仅修改className。

相同的Component

	<ComponentA a={1} />
---------------------------------
    <ComponentA a={2} />

React不会销毁ComponentA,componentWillReceiveProps 和componentWillUpdate将会被调用,之后render会被调用,diff算法将会进行递归比较原先的和当前的结果。

对于children的比较

默认情况下,React将会按顺序逐一与原先的children进行比较。

   <ul>
	  <li>first</li>
	  <li>second</li>
   </ul>
------------------------------------------
	<ul>
	  <li>first</li>
	  <li>second</li>
	  <li>third</li>
	</ul>

对于上面的情况,React会直接在ul的末尾插入

<li>third</li>

而不是重建整个ul的子节点。

<ul>
  <li>Duke</li>
  <li>Villanova</li>
</ul>
-----------------------------------------
<ul>
  <li>Connecticut</li>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

对于上面的情况,由于React是按顺序逐一比较的,React会认为所有的子节点都发生了变化,整个ul的子节点都会被重建。

key的使用

<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

<ul>
  <li key="2014">Connecticut</li>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

若使用了key,React会比较子元素的key值是否在原先的元素中存在过,若存在过,则该元素不会发生重建。对于上述情况,React只会新建一个元素:

<li key="2014">Connecticut</li>

因此我们在根据数组渲染元素的时候,最好不要把index设成key,当数组元素之间发生了交换,或者在数组头部或中间插入元素时,将会发生意想不到的现象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值