React Compiler 上生产一年:memo 可以删,但“静默退出”比收益更难发现
React Compiler 在 2025 年 10 月达到 1.0 稳定版,2026 年已经在大量生产代码库中运行。Meta 报告的数据是:初始加载和导航速度提升最高 12%,INP 从约 275ms 降到约 240ms,渲染时间和延迟减少 20% 到 30%。这些收益是真实的,但集中在一个特定的方向:交互速度,而不是初始加载。
更值得讨论的是它改变了什么。React Compiler 的核心是自动记忆化:它分析组件和 Hook,自动插入等价的 useMemo 和 useCallback,让开发者不再需要手写这些优化。2026 年的实践共识是:手写 useMemo 应该像现代 JavaScript 里手写 for 循环一样,偶尔必要,但通常是历史遗留物。在编译器启用 infer 模式之后,常规的“阻止列表行重渲染”场景不需要再手加 React.memo,编译器已经做了。
但编译器有一个需要警惕的失败模式:静默退出。当编译器遇到它无法安全分析的代码模式时,它会跳过那个组件或那个 Hook 的优化,而不是报错。从开发者的角度看,代码正常运行,测试通过,构建成功,但那个组件 quietly 失去了记忆化。如果这个组件恰好是性能敏感的,退化会以“某些交互变慢”的形式出现,而不是以任何显式的错误形式出现。
这个问题的工程应对不是“不要用编译器”,而是“知道它在什么情况下会退出,并且能检测到”。常见的退出原因包括:依赖了编译器无法追踪的可变值、在渲染期间做了副作用、使用了不受支持的语言特性。官方的 ESLint 插件会标记一部分问题,但它不是完备的。一个更可靠的实践是保留性能基准测试:在启用编译器前后,对关键交互路径跑同一组性能用例,对比结果。如果某个组件的渲染次数或交互延迟明显退化,再回去检查它是否被编译器跳过了。
另一个容易被低估的领域是第三方库兼容性。编译器假设组件是“纯”的,但很多库的 Hook 在内部依赖了编译器不理解的模式。react-hook-form 的用户报告过 useWatch 和 getValues 在编译器下遇到问题,官方的建议是在需要精确控制副作用依赖的地方,保留 useMemo 和 useCallback 作为应急出口。
一个务实的迁移路径是:先在代码库中启用编译器但保留现有的 memo 代码,跑性能基准和回归测试,确认没有静默退化;再逐步删除手写的 memo,每删一批跑一次对比;对性能敏感的交互路径,保留显式优化作为兜底。React Compiler 不是“删掉所有 memo 就完事”的魔法,它是一个有明确适用边界的优化层,知道它什么时候不工作,比知道它什么时候工作更重要。
- 点赞
- 收藏
- 关注作者
评论(0)