真实面经题目 · 原创解析
我把所有的组件都用 memo 包起来有什么问题?
这题考察 React 过度优化判断。回答要说明 memo 的比较成本、命中条件、引用稳定性、依赖复杂度和 Profiler 驱动优化。
真实面经题目 · 原创解析
这题考察 React 过度优化判断。回答要说明 memo 的比较成本、命中条件、引用稳定性、依赖复杂度和 Profiler 驱动优化。
把所有组件都用 React.memo 包起来通常不是好做法。memo 的收益来自 props 没变时跳过渲染,但它本身要做 props 浅比较。如果组件很轻、props 经常变化、父组件每次传新对象或新函数,memo 很难命中,比较成本和代码复杂度反而增加。为了让 memo 生效,开发者还可能到处加 useMemo/useCallback,带来依赖维护、闭包旧值和可读性问题。更合理的做法是用 Profiler 找到渲染频繁且耗时的组件,再针对稳定 props 的重组件局部使用 memo。
memo 只有在子组件渲染成本较高,并且 props 在很多次父渲染中保持浅比较相等时才有明显收益。轻组件或 props 总变化的组件,跳过机会少。
父组件每次渲染时,memo 组件都要做一轮 props 比较。props 很多、比较函数复杂或组件本身很轻时,比较成本可能接近甚至超过重新渲染成本。
对象字面量、数组字面量、内联函数每次 render 都会产生新引用。即使内容一样,浅比较也认为变化,memo 无法跳过渲染。
为了稳定引用,团队可能大量添加 useMemo/useCallback。这样依赖数组变多,漏依赖会产生旧闭包,多写依赖又让缓存频繁失效,代码阅读成本上升。
过度 memo 有时是在掩盖状态放得太高、组件边界太粗、列表项过重、上下文频繁变化等问题。真正的优化可能是状态下沉、拆分 context、虚拟列表或减少派生计算。
先用 Profiler 看哪些组件渲染频繁、耗时高、为什么渲染;再选择 memo、稳定 props、拆组件或调整状态结构。优化后再次测量,确认收益大于成本。
渲染成本较高、props 大部分时间稳定、父组件频繁渲染、且跳过渲染确实能带来收益的纯展示组件更适合。
组件内部读取的 context 变化时仍会重新渲染,即使 props 没变。可以拆分 context、选择器化读取或把读取 context 的部分和重组件分开。
不能。比较函数太深或太复杂会很贵,还可能因为比较不完整导致 UI 不更新。通常要谨慎使用。
可以状态下沉、拆分组件、拆分 context、虚拟列表、减少派生计算、延迟非关键渲染、缓存昂贵计算和优化数据结构。