1、React 的组件更新机制是怎样的?为什么要使用虚拟 DOM?
答:React的组件更新机制是:state/props 改变 → 生成新虚拟 DOM → Diff 对比 → 批量更新真实 DOM。React使用虚拟DOM的核心原因是减少不必要的DOM操作、提升性能、支持跨平台渲染,并通过Fiber架构实现可中断更新,让渲染更流畅。
React的组件更新流程大致分为触发更新→Reconciliation(协调)→Commit三个阶段:- 触发更新:当
state/props改变时,会触发组件更新。React会调用render()(或函数组件的执行),生成新的虚拟 DOM 树。 - Diff 算法(Reconciliation(协调) 阶段)
React将新生成的虚拟DOM与上一次的虚拟DOM进行Diff 对比。Diff算法的优化策略:- 同层比较:只比较同一层的节点,不会跨层级对比。
- 类型不同 → 直接替换。
- 类型相同 → 深入比较
props/children。 - 列表节点使用 key:
React通过key判断是否复用旧节点,否则可能导致不必要的销毁/重建。
- Commit 阶段 - 找出需要更新的部分后,
React会批量更新真实DOM。Fiber架构 支持更新任务可中断、分片执行,提升流畅度(避免大更新阻塞主线程)。
- 触发更新:当
为什么要使用虚拟 DOM?
- 传统
DOM问题- 直接操作真实
DOM的开销大(Reflow/Repaint)。 - 若频繁更新(如大列表、复杂
UI),性能下降严重。
- 直接操作真实
- 虚拟
DOM的优势- 最小化
DOM操作:React通过Diff算法,找出需要更新的最小差异,只更新必要节点。 - 跨平台能力:虚拟DOM 本质是一个JS对象,可渲染到
DOM、Native、Canvas(React Native、React Three Fiber)。 - 良好的开发体验:
React让开发者声明式写UI,框架内部处理优化逻辑(Diff + Fiber)。 - 提升性能(在复杂应用中):虽然虚拟
DOM本身有计算开销,但相比频繁DOM操作,整体性能更稳定,尤其在大规模组件树中效果明显。
- 最小化
2、React 中的 reconciliation(协调)算法是什么?
答:React的协调(Reconciliation)算法是用来比较新旧虚拟DOM树的过程。它的核心策略是:同层比较、不跨层级;不同类型直接替换;相同类型复用并更新属性;列表依赖 key 复用节点。
Reconciliation(协调)算法:是React在组件更新时,用来比较新旧虚拟DOM树并计算出最小化更新操作的过程。- 核心目标:找出哪些
DOM节点需要复用;哪些需要更新/删除/新增;最终生成需要应用到真实DOM的差异(patch)。 Diff算法优化策略- 同层比较,不跨层级:
React只会在 同一层级 比较新旧虚拟DOM,不会递归跨层对比。如果节点层级变化,React直接销毁旧节点并创建新节点。 - 节点类型不同 → 直接替换:如果新旧虚拟
DOM的元素类型不同(如<div> → <span>),React直接销毁旧节点及其子树,然后创建新节点。 - 节点类型相同 → 复用并更新属性:如果类型相同(如
<div> → <div>),React会:保留DOM节点;对比props并更新不同的属性;递归对子节点进行协调 - 列表
Diff依赖key:列表渲染时,React通过key判断元素是否相同;如果key一致,复用该节点;如果不一致,则认为是新元素,销毁并重建;错误示例:用数组下标做key→ 导致节点复用错误(比如输入框内容丢失)。
- 同层比较,不跨层级:
3、什么是fiber架构?它解决了React哪些问题?
答:Fiber架构是React16引入的新协调引擎。它的核心作用是让更新过程可中断、可恢复、可分片执行,并支持 任务优先级调度。解决了React15以前渲染不可中断、长任务阻塞主线程、导致页面卡顿的问题。这使得React可以更好地支持高优先级的交互响应、流畅的动画,整体用户体验提升。
什么是Fiber架构?
- Fiber 架构 是
React16引入的一种新的协调(Reconciliation)实现机制。 - 简单理解:
React以前的协调过程是一口气跑完的,而Fiber把更新过程切分成小任务块(fiber单元),让React能够在合适的时候暂停、恢复、甚至丢弃任务。 Fiber可以看作是虚拟DOM的数据结构 + 异步可中断的任务调度器
React15及以前的问题
Reconciliation是同步的- 一旦开始
Diff,必须把整个虚拟DOM树比较完,不能中断。 - 如果组件树很大(成千上万个节点),更新可能会占用主线程几十毫秒甚至更长。
- 一旦开始
- 阻塞用户交互
- 浏览器主线程不仅负责
JS,还要处理用户交互(点击、输入)、动画(requestAnimationFrame)、布局/绘制。 - 如果
React更新长时间占用线程,就会导致:动画掉帧、卡顿;输入延迟,交互不流畅。
- 浏览器主线程不仅负责
Fiber 架构解决了什么问题?
- 可中断的渲染
Fiber把渲染任务拆成一个个小的Fiber节点(对应虚拟DOM节点)。- 每次只处理一部分,如果主线程有更高优先级的任务(如用户输入),
React可以暂停渲染,先去响应用户操作。
- 任务优先级调度
- 每个
Fiber节点都有优先级(expirationTime)。 - 高优先级(用户输入) → 立即执行。
- 低优先级(长列表渲染) → 延后或分片执行。
- 每个
- 渲染分片(时间切片)
React利用requestIdleCallback / MessageChannel实现时间切片。- 把长任务切成小任务,空闲时再执行,避免卡死。
- 更细粒度的更新控制
Fiber是链表结构(而不是树递归),可以做到:按需遍历、任务暂停/恢复、精确控制哪些子树需要更新。
4、React 18 引入的 concurrent features(并发特性) 是什么?如何工作?
答:React18的Concurrent Features(并发特性)是基于Fiber架构实现的新渲染模式。让React渲染任务:可中断(渲染可以暂停,而不是一口气做完)、可恢复(暂停后可继续执行)、可丢弃(如果有更高优先级任务,可以放弃之前的渲染)。核心目标:避免低优先级更新阻塞高优先级任务,让交互更流畅。
React15及之前:使用Stack Reconciler,渲染是同步的、不可中断的;大组件树渲染时,页面容易卡顿。React 16 / 17:引入Fiber架构,具备了“切片、调度”的能力;但渲染模式默认还是同步的(并发特性没有启用)。React 18:默认启用Concurrent Rendering(并发渲染);通过createRoot开启;真正实现了任务可调度,提升用户体验。- 原理:
React18内置了一个Scheduler 调度器:- 把渲染任务切分成很多小片段
- 每执行一段就检查:
- 是否有更高优先级任务(例如用户输入)
- 有 → 先暂停低优先级渲染,优先执行高优先级
- 没有 → 继续渲染
- 用户交互(高优先级)始终流畅,耗时渲染(低优先级)延迟执行。
- 关键
APIstartTransition:标记某些更新为“非紧急”,允许React延迟执行
import { startTransition } from 'react'; startTransition(()=>{ setList(newBigList); // 低优先级更新 })useTransition:Hook 版,能拿到isPending状态
const [isPending, startTransition] = useTransition();useDeferredValue:延迟一个值的更新,避免频繁触发渲染改进的 Suspense:支持异步数据加载,不再只针对代码分割
- 使用场景
- 搜索框:输入框内容即时更新,搜索结果延迟渲染
- 大列表渲染:保持滚动流畅,列表项逐步渲染
- 动画:动画保持不卡顿,数据更新延后执行