1、简述fiber架构
参考文章:
juejin.cn/post/701651…
mount——初次挂载
组件的初始化阶段,在组件的生命周期中置只会进行一次。
render
fiberRoot: 首次构建应用, 创建一个 fiberRoot ,作为整个 React 应用的根基
rootFiber: 使用ReactDOM.render(<App />, container)或在React 18+中使用ReactDOM.createRoot(container).render(<App />)来渲染应用时,实际上会创建一个单一的FiberRoot节点。无论是传统的ReactDOM模式还是使用新的并发模式,对于每一个ReactDOM.render或createRoot调用,在其对应的DOM容器(通常是一个HTML节点,比如一个div元素)上,都会创建一个FiberRoot节点
第一次挂载的过程中,会将 fiberRoot 和 rootFiber 建立起关联。
react 对于 fiber 结构的创建和更新,都是采用深度优先遍历。
调和
beginWork:是向下调和的过程。就是由 fiberRoot 按照 child 指针逐层向下调和,期间会执行函数组件,实例类组件,diff 调和子节点,打不同effectTag。
completeUnitOfWork:是向上归并的过程,如果有兄弟节点,会返回 sibling兄弟,没有返回 return 父级,一直返回到 fiebrRoot ,期间可以形成effectList,对于初始化流程会创建 DOM ,对于 DOM 元素进行事件收集,处理style,className等
commit
1、before mutation
执行useEffect
2、mutation
3、layout
执行useLayoutEffect
update——更新
组件的props和state发生变化之后,组件就会重新渲染。
render
update 时,react 会根据新的 jsx 内容创建新的 workInProgress fiber,还是通过深度优先遍历,对发生改变的 fiber 打上不同的 flags 副作用标签,并通过 firstEffect、nextEffect 等字段形成 Effect List 链表。
current fiber 和 workInProgress fiber 中对应的 alternate 会相互指向,然后 workInProgress fiber 完全创建完成后,fiberRoot 的
current 字段的指向会从 current fiber 中的 rootFiber 改为 workInProgress fiber 中的 rootFiber。
双缓存树
当发生一次update,workinprogress树准备完毕,workinprogress树就会通过commit变为current树,之前的current树可能会被垃圾回收,但这不是立即发生的。React 内部有一个缓存机制,它会保留一些旧的 Fiber 节点,以防它们在未来的更新中被重用(复用)。
React 的垃圾回收策略采用惰性,也即是说,不会立即清除不再需要的 Fiber 节点,而是等待垃圾回收机制触发时将它们清除。在绝大部分情况下,开发者不需要关心这一层的清理工作,因为 React 和浏览器的垃圾回收器会处理这些事情
在生成workinprogress树的过程中,对于需要更新和不需要更新的节点处理方式是不同的:
- 对于不需要更新的节点:workinprogress树上的节点会直接引用(或将地址指向)current树上相同位置的fiber节点,在这种情况下workinprogress树上的节点和current树上的节点会指向同一个内存地址,这样处理会节省创建一个新的节点的成本,减少了内存分配的压力和垃圾回收的压力,提升了性能
- 对于需要更新的节点:对于需要更新的节点,workinprogress树会浅克隆current树上的的节点,然后与新的react element进行比较,浅克隆指的是浅层发复制了节点本身的配置,包括指针、状态、props等,而节点子树通常会在后续渲染的过程中被重新创建或更新
调和
beginWork:是向下调和的过程。就是由 fiberRoot 按照 child 指针逐层向下调和,期间会执行函数组件,实例类组件,diff 调和子节点,打不同effectTag。
completeUnitOfWork:是向上归并的过程,如果有兄弟节点,会返回 sibling兄弟,没有返回 return 父级,一直返回到 fiebrRoot ,期间可以形成effectList,对于初始化流程会创建 DOM ,对于 DOM 元素进行事件收集,处理style,className等
commit
1、before mutation
执行useEffect
2、mutation
3、layout
执行useLayoutEffect
hooks
hooks会在fiber节点里生成一条hook链表,在生成workinprogress树的时候,复制fiber节点的同时也会复制hook链表