参考自: react diff算法浅析
复杂度
react diff算法由Tree比较的复杂度O(n3)变成了O(n),是怎么做到的呢?
3个策略
- Tree Diff 这一步是普通的Tree的比较,先比较父节点,再比较子节点。 但是会出现一个问题,那就是跨层级操作时
createA-->createB-->createC-->deleteA
如上图,dom本身没有改变,只是换了个父节点,但是Tree Diff的缺陷,会销毁后在创建新节点,而不会直接移动,所以跨层级操作在react中是比较耗费性能的。
ps: react16 中可以使用 createPortal 将组件挂载到父节点外的地方,vdom 中还可以保持不变的父子结构。
- Component Diff
1) 不是同一类型的
component,简单,整段垮掉,换组件 2)是同一类型,那咱就比较state和props,记录下变化,再比较children,同样进行component diff,记录下变化patch,之后再某个时间点统一更新(这就是为啥setState是异步的),咱可以通过操作shouldComponentUpdate来优化,不再比较children - Element Diff
到这一层就是同级的节点的比较了,这一比较中主要有三个操作
INSERT_MARKUP(插入),MOVE_EXISTING(移动),REMOVE_NODE(删除)很明显的字面意义就不解释了, 这个阶段可以的优化的就是使用数组生成节点是加上key值,当key值相同,react不会去更新此组件,只是会相应的移动位置,不建议使用index作为key值,除非是确定了不会改变的。
react 的 Tag 消失, 真实dom中消失了,但是在虚拟dom中还是存在的,重新渲染时,会对该组件进行渲染,但是dom节点已经不存在了