虚拟DOM和react中的diff算法总结
一、虚拟DOM
1.什么是虚拟DOM及原理
把真实DOM树,变成js对象树,将之前的和新的作比较,通过diff算法,按照不同的地方进行渲染。
2.什么情况下使用虚拟DOM
当修改组件内部状态时,如props或state发生改变。
二、diff算法
1.使用传统的diff算法进行节点的循环遍历,复杂度是 O(n^3)。
2.diff
是逐层比较的算法,一旦发现节点消失,就删除,一旦发现新节点,就创建,发现相同的,就保留。
3.缺点:
(1)两棵树变化非常陡峭,是低效的。
(2)兄弟节点排序和插入新节点是低效的。
4.diff的两个重要假设,如下图:
第二个假设是通过加key值来来区别兄弟节点。key不能使用index值,在插入数据时会产生新的问题,因为标识的index对应的值会发生变化。但是可以给index加“”,避免产生混淆。但最好使用id值。
同层key值不能相等,不同层没有影响。
![](https://img2018.cnblogs.com/blog/1459189/201811/1459189-20181126092930689-1634467686.png)
5.diff算法
(1)同层级的比较
有3种方式,删除、移动和添加。
(2)跨层移动:
只进行同层级的比较,如果不同层级,不进行比较。如果进行跨层移动的话,它直接将移除地方的节点删除掉,移入地方添加新的节点,而不是进行移动。这样只需进行一次比较。这样就将复杂度降低为O(n),但不建议跨层移动。
![](https://img2018.cnblogs.com/blog/1459189/201811/1459189-20181126092912748-1383427056.png)
(3)不同组件:
react是基于组件的,同组件比较用虚拟DOM,不同组件直接删除掉,重新渲染。当出现如下情况是,跨层级,react自动认为不是同一个组建,删点重构所有子组件。如下图,直接把D及其子节点,换成G及其子节点。
下图的D和G虽然结构相似,但是react断定不是同一类型的组件,虽然这样很耗费性能,但这种情况在react里很少踹出现。
![](https://img2018.cnblogs.com/blog/1459189/201811/1459189-20181126092905725-903029246.png)
如果还不明白,可以看看这篇随笔:https://www.cnblogs.com/wzndkj/p/10520697.html