react diff算法浅析

486 阅读1分钟

参考自: react diff算法浅析

复杂度

react diff算法由Tree比较的复杂度O(n3)变成了O(n),是怎么做到的呢?

3个策略

  1. Tree Diff 这一步是普通的Tree的比较,先比较父节点,再比较子节点。 但是会出现一个问题,那就是跨层级操作时

createA-->createB-->createC-->deleteA

如上图,dom本身没有改变,只是换了个父节点,但是Tree Diff的缺陷,会销毁后在创建新节点,而不会直接移动,所以跨层级操作在react中是比较耗费性能的。

ps: react16 中可以使用 createPortal 将组件挂载到父节点外的地方,vdom 中还可以保持不变的父子结构。

  1. Component Diff 1) 不是同一类型的component,简单,整段垮掉,换组件 2)是同一类型,那咱就比较stateprops,记录下变化,再比较children,同样进行component diff,记录下变化patch,之后再某个时间点统一更新(这就是为啥setState是异步的),咱可以通过操作shouldComponentUpdate来优化,不再比较children
  2. Element Diff 到这一层就是同级的节点的比较了,这一比较中主要有三个操作INSERT_MARKUP(插入)MOVE_EXISTING(移动)REMOVE_NODE(删除) 很明显的字面意义就不解释了, 这个阶段可以的优化的就是使用数组生成节点是加上key值,当key值相同,react不会去更新此组件,只是会相应的移动位置,不建议使用index作为key值,除非是确定了不会改变的。

react 的 Tag 消失, 真实dom中消失了,但是在虚拟dom中还是存在的,重新渲染时,会对该组件进行渲染,但是dom节点已经不存在了