React 列表性能优化

React 列表性能问题的主要来源,以及 key、渲染边界、虚拟列表和数据更新方式之间的关系。

#tech / dev / frame #resource / react #type / synthesis #status / growing

[!info] related notes

React 列表性能优化

React 列表性能问题很少只靠一个 memo 就能解决,真正要看的是列表为什么慢:是节点太多、更新太频繁,还是每次都让整片列表重复执行。

一句话定义

React 列表优化的核心是减少不必要的节点数量、减少不必要的重新执行,以及保证每一项的身份稳定。

列表为什么会慢

  • 一次性渲染的节点太多
  • 列表项更新时整片列表都重新执行
  • key 不稳定导致节点复用失效
  • 父组件每次都传入新的对象或函数 props

最常见的优化方向

先保证 key 稳定

  • key 影响 React 识别列表项身份
  • 错误 key 会放大重排、状态错位和无效更新问题

再缩小渲染边界

  • 不要把只影响单行的状态放到过高层
  • 把局部交互尽量留在局部组件里
  • 必要时再考虑 React.memo 这类边界优化

再看 props 身份是否稳定

  • 列表项接收的新对象或新函数可能让优化失效
  • 优化前先确认是不是真的存在重复执行成本

节点过多时考虑虚拟列表

  • 如果瓶颈来自 DOM 数量太大,虚拟列表往往比细抠 Hook 更有效
  • 它本质上是减少同时存在的真实节点数量

常见误区

  • 看到列表卡顿就先全量加 useMemouseCallback
  • 把列表性能问题全归因于 React 本身
  • 只看 JavaScript 执行,不看真实 DOM 数量和滚动渲染成本

最短记忆方式

先保身份稳定,再缩边界,节点太多就上虚拟列表。

面试要点

来自 react-list-performance-optimization-interview-question 的面试视角整理。

一句话回答

React 长列表优化通常先看 key 是否稳定、状态和渲染边界是否合理,再看 props identity 是否导致无效更新;如果瓶颈来自节点数量过多,就优先考虑虚拟列表。

最稳的回答主线

  • 第一层看列表项身份:key 要稳定
  • 第二层看渲染范围:别让局部交互带动整片列表一起执行
  • 第三层看引用稳定性:对象和函数 props 可能让优化边界失效
  • 第四层看节点数量:DOM 太多时用虚拟列表比细节缓存更有效

一个更完整的面试表达

可以这样答:

长列表优化我一般不会一上来就说 memo。我会先分四层看:
第一层是 key 是否稳定,先保证列表项身份正确;
第二层是状态和渲染边界是否合理,避免局部操作带动整片列表一起重算;
第三层才看对象和函数 props 的引用稳定性;
如果问题的根源是同时渲染了太多 DOM 节点,那重点通常不是“让每一项更便宜”,而是直接上虚拟列表做窗口化。

一个典型答题结构

  1. 先保证 key 正确
  2. 再收紧状态边界
  3. 再考虑 React.memouseMemouseCallback
  4. 节点量太大就上虚拟列表

为什么虚拟列表经常是关键

因为当瓶颈来自“同时挂了几千个节点”时,哪怕每个节点都稍微优化一点,收益也可能不如直接减少可见节点数量。

面试里容易加分的一句

如果问题主要是同时渲染了上千个节点,那重点往往不是“让每个节点更便宜”,而是“不要同时渲染这么多节点”。

常见追问

  • 为什么 index 不适合当 key
  • React.memo 在列表里什么时候值得用
  • 虚拟列表解决的是 React 问题还是 DOM 问题

最短记忆方式

先看身份和边界,再看引用,节点太多就做窗口化。

创建于 2026/3/19 更新于 2026/5/27