React为什么从根节点开始diff?*
- 简化算法实现,从根节点开始遍历树结构更符合树的遍历逻辑。如果从状态变化的组件开始, React就需要追踪依赖,确定到底是哪个节点受影响了,有几个节点受影响了, 状态变化也会有useState/useContext多种种类, 倒不如直接从根节点一遍过,虽然会牺牲一点点的遍历时性能,但无关紧要。目前到v18为止,React不会追踪依赖。
- React会使用Bailout策略,如果React在某个节点的渲染过程中确定该节点没有发生变化, 就会放弃(bailout)继续对该节点进行深度比较。从这个方面来说,从根节点开始遍历也不会耗费太多性能。
- React内部,还大量使用了以从根节点开始diff思想的逻辑,比如说优先级任务复用,会导致该任务上下文混乱,因此无法定向渲染。
- 即便从状态改变组件开始diff,如果该组件需要构造一个新的fiberNode,那么它的父组件,兄弟组件的指针是不是要改一下? 父组件可以通过return属性找到,但是上一个兄弟节点可就不好找了。 如果该组件的fiberNode还是复用原来的,但是它的子节点肯定都是新的fiberNode了, 那么至少useEffect以及各种钩子,在这里就需要差异化执行,相当于两种fiberTask。 因此从状态改变组件开始diff也不是一个十全十美的好方法。