第2章 React核心原理与虚拟DOM:diff算法、Fiber架构与调和过程
本章集中剖析React运行时的三大核心:虚拟DOM的diff策略、Fiber的可中断调度机制、以及从触发更新到commit的完整调和流程。面试中高频出现,要求既能从宏观流程描述,又能深入细节说明数据结构与调度方式。下面用回答框架图、对比表格和三组问答卡片帮你构建清晰应答结构。
核心概念对比
| 概念 | 核心思想 | 关键数据结构 | 主要作用 |
|---|---|---|---|
| Diff算法 | 层级比较 + key复用 | 虚拟DOM树 | 最小化DOM操作 |
| Fiber架构 | 可中断、分片调度 | Fiber节点(链表) | 实现异步渲染与优先级 |
| 调和过程 | 触发→构建→diff→commit | workInProgress + effectList | 整体协调更新流程 |
面试问答卡 ① 虚拟DOM的diff算法原理
问题:请解释React中虚拟DOM的diff算法原理?
面试官考察点:
- 是否了解diff的三大策略(层级、类型、key)
- 能否说清为什么复杂度是O(n)而不是O(n³)
- 对key在列表diff中的作用的理解深度
回答框架:
- 树比较按层级,只对比同级节点;
- 根节点类型不同则整棵子树重建;
- 列表diff通过key唯一标识进行位移、复用;
- 最终将算法复杂度从O(n³)降为O(n)。
简短示例回答:
React采用同级比较策略,先判断根节点类型,不同则直接替换整个子树;相同则递归对比子节点。对于列表,通过key值在旧集合中寻找可复用的节点,进行插入、移除或移动。这种启发式算法将diff复杂度从理论O(n³)优化到O(n)。
可能追问:
- 为什么React不直接操作真实DOM?
- key值不唯一或不稳定会有什么后果?
- 列表diff在没有key的情况下怎么工作?
⚠ 避坑提醒:不要只背“O(n³)→O(n)”的结论,要解释“同级比较”“类型比较”“key复用”这三条具体策略。强调key应稳定且唯一,index作为key会导致列表项顺序变化时的无效渲染。
面试问答卡 ② Fiber架构的核心思想与作用
问题:React Fiber架构的核心思想和作用是什么?
面试官考察点:
- 对Fiber节点数据结构(链表)的认识
- 能否说清“可中断”依赖的机制(双缓冲、workLoop)
- 对优先级调度和React18并发模式的理解
回答框架:
- Fiber节点=组件单元+状态+副作用链表;
- 双缓冲树(current / workInProgress)实现增量构建;
- workLoop配合requestIdleCallback实现可中断&恢复;
- lane模型管理优先级,高优先级任务可打断低优先级。
简短示例回答:
Fiber把渲染任务拆成一个一个的Fiber节点,每个节点保存组件实例、状态和副作用。通过维护current树和workInProgress树,实现“一边渲染一边保存进度”,配合浏览器空闲时间调度,使渲染过程可中断、可恢复,保证高优先级更新(如用户输入)不被卡顿。
可能追问:
- Fiber节点上有哪些核心字段?
- 如何实现“可中断”?中断后如何恢复?
- React18的并发模式与Fiber有什么关系?
⚠ 避坑提醒:不要只笼统说“Fiber是新的调和引擎”,要讲清楚“Fiber = 链表结构 + 双缓冲 + 可中断调度”。同时避免混淆Fiber与虚拟DOM:虚拟DOM是React元素树,Fiber是组件树的运行时表示。
面试问答卡 ③ 调和(Reconciliation)全过程
问题:描述React的调和(Reconciliation)过程?
面试官考察点:
- 能否画出从触发更新到commit的完整流程
- 区分调度(schedule)、调和(reconcile)、提交(commit)三个阶段
- 理解Fiber树创建、diff、副作用收集在流程中的位置
回答框架:
- 触发更新:setState/useState产生更新对象;
- 调度:将更新加入队列,确定优先级;
- 构建workInProgress树:从FiberRoot向下遍历,递归执行beginWork;
- Diff & 构建Fiber节点:对比新旧虚拟DOM,生成新Fiber并收集effectTag;
- 完成 & 提交:构建effectList,commit阶段按顺序执行DOM操作。
简短示例回答:
调和从组件状态更新开始,React计算优先级后进入workLoop,创建workInProgress树。在beginWork中执行diff,生成新的Fiber节点并标记副作用(插入、更新、删除)。所有节点完成后,将副作用列表提交给渲染器,依次执行真实的DOM操作,完成视图更新。
可能追问:
- 调和和diff是同一个概念吗?
- schedule阶段和reconcile阶段如何衔接?
- commit阶段又分为哪几个子阶段?
⚠ 避坑提醒:调和 ≠ diff,diff只是调和中的一个子步骤。一定要提到调度(schedule)阶段的优先级队列,否则显得对Fiber理解不完整。同时强调workInProgress树的构建是在beginWork/completeUnitOfWork的循环中完成的。