React Fiber
特点
- 是一种数据结构,通过链表的方式形成 Fiber 树
- child(子节点),return(父节点),sibling(下一个兄弟节点)。这样可以实现快速查找以及回溯。
- 因为以上的数据结构,实现可中断机制
- fiber.alternate: 指向内存中的另一个 fiber, 每个被更新过 fiber 节点在内存中都是成对出现(current 和 workInProgress)(双缓冲机制)
- fiber 树跟 ReactElement 树并不完全一一对应。比如
<XXXX> 组件在 ReactElement 树中是一个 React.Fragment 节点,然后它的 props.children 就是 XXXX 里包含的子节点。但是 fiber 树中没有 React.Fragment 对应的 fiber 节点。比如<div><XXXX><p /><XXXX><span /></div>
- Fiber 与 ReactElement 互相引用
优势
- 可中断的渲染
- Fiber 允许 React 在渲染过程中中断任务,优先处理高优先级任务(如用户输入)。
- 这可以避免页面卡顿,提升用户体验。
- 优先级调度:
- Fiber 支持根据任务的优先级动态调整执行顺序。
- 例如,用户输入可以立即响应,而数据加载可以稍后处理。
- 增量渲染:
- Fiber 将渲染任务拆分为多个小任务,可以在多帧中逐步完成渲染。
- 这可以减少单次渲染的时间,避免阻塞主线程。
- 支持并发模式:
- Fiber 是 React 并发模式(Concurrent Mode)的基础。
- 并发模式允许 React 同时处理多个任务,进一步提升性能。
Fiber 的应用场景
- 大型应用:在组件树很大的情况下,Fiber 可以避免一次性渲染导致的卡顿。
- 高交互性应用:在需要快速响应用户输入的场景中,Fiber 可以优先处理用户交互,提升体验。
- 复杂动画:Fiber 的增量渲染机制可以确保动画的流畅性。
Fiber 的可中断机制
- Fiber 架构可以实现任务的可中断,比如在进行渲染的时候,有高优先级的任务进来(如动画、用户输入),那么渲染任务就会被中断,优先处理高优先级任务
- 但这会导致一些旧的生命周期方法被重复调用比如(ComponentWillMount),在渲染任务没有结束前这个方法被调用过,然后任务中断,再重新执行渲染任务的时候,这个方法又会被再次调用,因此设计了 useEffect 来处理副作用会更好。
VDom(虚拟 Dom)
虚拟 Dom 是对真实 Dom 的一种抽象的结构化数据。
主要作用:
- 跨平台渲染
- 替代直接操作 Dom,有可能一定程度上提升性能,减少开销。避免过多的 reflow 和 repaint。
- 开发者不需要再手动操作 Dom,只需要关注 UI 的变化。
- 便于使用 diff 算法计算出需要更新的 Dom 节点。
缺点
- 内存消耗变大,需要维护 VDom
- 首次渲染变慢,因为需要生产 VDom 再渲染成真实的 Dom
- 不适合简单的场景,直接操作 Dom 反而效率更高,VDom 会带来额外的计算和对比的开销、
Diff 算法
- 同级比较:Diff 算法只比较同一层级的节点,不跨层级比较。如果节点类型不同,React 会直接销毁旧节点并创建新节点。
- Key 值优化:通过 key 属性识别节点的唯一性,React 可以更高效地复用节点。
- 时间复杂度:Diff 算法的时间复杂度为 O(n),其中 n 是节点的数量。React 通过一些启发式规则(如只比较同一层级的节点)来优化性能。