Skip to content

React 性能优化

为什么状态下沉和状态就近放置能提升 React 性能?

状态放得越高不代表架构越好,高频变化状态应尽量靠近真正读取它的组件。

适合阶段:高级前端 / 资深前端核心能力:状态所有权 · 更新范围 · 组件架构

面试官想考什么

  • 为什么全局 state 可能拖慢页面? 考察订阅范围。
  • 状态下沉会不会导致数据难共享? 考察架构取舍。
  • 何时提升状态、何时使用 Context? 考察状态建模。
  • 如何证明下沉有效? 考察性能验证。

一句话回答

text
状态就近放置可以缩小更新传播和订阅范围,让高频输入、hover 或动画变化不必重新评估整棵页面树。

面试回答详解

1. 状态位置的判断

  • 局部交互状态:放在使用它的组件附近。
  • 兄弟共享状态:提升到最近公共父组件。
  • 跨领域状态:使用外部 store,并提供细粒度订阅。
  • 服务端数据:放在查询缓存或服务端数据层,不等于全局 UI state。

2. 为什么下沉有效

text
高频输入 state 在页面根部 -> 大范围 render
高频输入 state 在输入组件内 -> 局部 render

状态放在页面根部时,每次更新都会让包含大量无关子树的父组件重新评估。把状态放到叶子附近,能缩短传播路径,减少比较、计算和提交。

3. 不是绝对规则

如果多个区域必须同步,就要提升状态或使用外部 store;过度下沉可能造成状态重复和跨组件协调复杂。关键是单一事实来源与明确订阅边界。

4. 验证与风险

通过 Profiler 对比提交耗时、更新组件数量、输入 INP 和长任务。注意不要为了局部速度破坏可访问性、撤销能力或业务一致性。

可直接背诵的 30 秒回答

text
我会按状态的共享范围和变化频率决定放置位置。局部高频状态尽量下沉,兄弟共享状态提升到最近公共父组件,跨领域状态用细粒度 store,服务端数据交给查询缓存。这样可以减少无关子树的 render 和 commit,但如果多个区域确实需要同步,就要优先保证单一事实来源,再用 Profiler 和 INP 验证收益。

扩展知识

状态放置决策

text
谁读取 -> 多久变化 -> 是否跨路由 -> 是否服务端来源 -> 选择所有权

面试官追问链

追问一:所有状态都下沉会有什么问题?

  • 考察点:是否理解状态共享成本。
  • 回答方向:可能导致状态重复、同步逻辑和跨组件通信增加;共享状态应放在最近公共边界或专门 store。

追问二:Context 能解决状态范围问题吗?

  • 考察点:是否区分传递和订阅。
  • 回答方向:Context 解决跨层传递,但 value 变化会影响消费者;需要拆分 Context 或使用细粒度订阅。

追问三:下沉后如何保留表单草稿?

  • 考察点:是否会区分生命周期。
  • 回答方向:根据需求把草稿放在表单域、路由级 store 或持久化层,明确卸载、返回和刷新时的恢复策略。

推荐阅读

基于 MIT 协议开源