渲染机制与性能优化
面试核心就三句:什么触发渲染 → 渲染了谁 → 怎样缩小范围 / 降低成本。
渲染 ≠ 浏览器 paint
React 语境里「渲染」多指:组件函数又执行了一遍,算出新的 Virtual DOM / 元素描述,再交给协调(reconcile)决定改哪些真实 DOM。
浏览器的 layout / paint 是下一步;能少改 DOM、少跑重组件,体感 才快。
什么会触发一次更新
常见来源:
- 本组件
useState/useReducer的 set - 父组件 重渲染 → 默认子组件也会再执行(除非被 memo 挡住且 props 浅相等)
- Context 值变化 → 所有消费该 Context 的组件更新
- 外部 store 订阅(Redux / zustand 选择器命中等)
function Parent() {
const [n, setN] = useState(0)
return (
<>
<button onClick={() => setN(n + 1)}>{n}</button>
<Child /> {/* Parent 一更新,Child 默认也会跑 */}
</>
)
}
协调与 key
同层对比时,React 靠 位置 + type + key 判断节点是否可复用。
// ❌ index 当 key:中间插入/删除会错位复用,状态「串台」
{list.map((item, i) => <Row key={i} item={item} />)}
// ✅ 稳定业务 id
{list.map((item) => <Row key={item.id} item={item} />)}
面试怎么答 key:
- 帮助 reconcile 识别「是同一个组件实例」
- 列表重排、插入时,错误 key 会导致 state 挂错行、多余卸载挂载
- 静态列表用 index 偶尔能混,动态列表别用
React.memo:浅比较 props
const Row = memo(function Row({ item, onSelect }: Props) {
return <div onClick={() => onSelect(item.id)}>{item.name}</div>
})
注意:
- 默认 浅比较 props
- 父组件每次
onSelect={() => ...}新函数 → memo 形同虚设 → 配useCallback或把回调稳到 store - 不是越多越好:比较本身有成本;先优化「谁在更新、更新面多大」
常见性能手段(按性价比)
| 手段 | 解决什么 | 备注 |
|---|---|---|
| 状态下沉 / 提升合理范围 | 无关兄弟少更新 | 往往比 memo 更治本 |
| 列表虚拟化 | 只渲染可视区 | 大表必问 |
| 选择器订阅(zustand 等) | 少订阅字段 | 见状态管理 |
| 拆 Context | 避免「一个大 value 全家重渲染」 | value 用 memo 或拆多个 Context |
useTransition | 紧急更新优先 | 见并发特性 |
memo + 稳定 props | 挡纯展示子树 | 先保证 props 引用稳 |
Context 的坑
// ❌ 每次 Parent 渲染都是新 value 对象 → 所有 Consumer 更新
<Ctx.Provider value={{ user, theme }}>
// ✅ 拆开,或 useMemo value,或别用 Context 扛高频变化的数据
高频、细粒度状态(输入框每个字符)更适合局部 state / 外部 store,而不是顶层 Context。
列表与表格(常考)
- key 用稳定 id
- 行组件 memo,行 props 尽量原始值或稳定引用
- 虚拟列表(只挂载可视行)
- 避免在 render 里
list.map出又过滤又排序的大金句还不缓存——大数据用useMemo或上游算好
怎么排查
面试也可提工具链:
- React DevTools Profiler:谁花了时间、为什么 render(props/hooks 变化)
- 先看「更新面是否过大」,再看「单次 render 是否过重」
面试速答清单
- 父更新子为什么也更新? → 默认递归渲染;memo + props 不变可跳过。
- memo 失效最常见原因? → 内联对象/函数 props 每次新引用。
- key 用 index 有什么问题? → 列表变序时复用错乱,局部 state 错位。
- Context 性能问题? → Provider value 变,所有消费者更新;高频数据慎用大 Context。
- 优化顺序? → 减更新范围 → 减渲染成本 → 再考虑 memo/虚拟列表/并发特性。
上一篇:Hooks 核心与常见坑 · 下一篇:Fiber 与调度直觉