一句话总结:2025年10月 React Compiler v1.0 稳定版发布,Next.js 16、Vite、Expo 已内置支持。useMemo、useCallback、React.memo 不再是日常必需品,但「告别」不等于「抹掉」——理解原理依然重要。
从 React Forget 到 Compiler v1.0:一段近十年的旅程
React Compiler 的故事,比大多数人想象的更长。
早在 2018 年,Meta 内部就启动了一个代号为 React Forget 的研究项目——目标是让 React 的重新渲染优化自动化。经历了多年的内部验证、反复重写,终于在 2024 年 React Conf 上首次以实验性功能公开亮相。
| 时间 | 事件 |
|---|---|
| 2018 | Meta 内部启动「React Forget」项目 |
| 2024.05 | React Conf 公开亮相,更名为 React Compiler |
| 2025 Q1 | 进入 RC 阶段 |
| 2025.10 | v1.0 稳定版发布,内置 eslint 规则和迁移指南 |
| 2025 Q4 | Next.js 16 稳定支持 |
| 2026 | Vite、Expo 全面内置,编译器成为新建项目的默认选项 |
2025 年 10 月 7 日是真正值得标记的一天。React 团队在官方博客宣布 Compiler v1.0 稳定版,并同时发布了:
- 内置 lint 规则——
eslint-plugin-react-hooks的recommended预设中包含了 compiler 驱动的诊断 - 渐进式迁移指南——支持逐模块启用
- 官方模板——与 Expo、Vite、Next.js 合作,新项目开箱即用
React Compiler 到底做了什么?
React Compiler 是一个 构建时 Babel 插件。它在编译阶段遍历你的组件和 hooks,分析依赖关系,自动注入 memoization 代码。
// 以前:手动优化
function ProductList({ products, onSelect }) {
const sortedProducts = useMemo(() => {
return [...products].sort((a, b) => a.price - b.price);
}, [products]);
const handleClick = useCallback((id) => {
onSelect(id);
}, [onSelect]);
return <List items={sortedProducts} onSelect={handleClick} />;
}
// 现在:编译器自动处理
function ProductList({ products, onSelect }) {
const sortedProducts = [...products].sort((a, b) => a.price - b.price);
const handleClick = (id) => onSelect(id);
return <List items={sortedProducts} onSelect={handleClick} />;
}
编译器在构建时分析代码的「形状」:
- 识别组件和 hooks(按命名约定:PascalCase 组件、useXxx hooks)
- 追踪依赖关系图——包括可选链、数组索引等复杂场景
- 生成编译后的优化代码,等价于手动插入了
useMemo、useCallback和React.memo
你可以把编译器想象成一个 自动帮你写完 useMemo 的机器人,而且它不会犯「漏了依赖」或「写了多余依赖」这种人类常犯的错误。
「告别」不是「抹掉」
这里有一个关键的认识误区。React Compiler 并没有删除 useMemo 和 useCallback API,而是让你 在日常开发中不再需要手动操心它们。
| 不需要手动写 | 仍需了解原理 |
|---|---|
| 大多数组件的重渲染优化 | 调试性能问题时需看编译产物 |
| 函数引用的稳定性保证 | bail-out 场景(eval、动态 import) |
| 列表项的 memoization | 与第三方库的互操作 |
| 简单派生数据的缓存 | "use memo" 指令的使用 |
编译模式
React Compiler 支持两种编译模式:
infer模式(默认):编译器自动检测组件和 hooks,按命名约定推断哪些需要优化。大多数项目使用这个模式就够了。annotation模式:你需要用"use memo"指令显式标记要优化的函数。适合精细控制或遗留项目过渡。
"use memo"; // 标记整个文件
function ExpensiveComponent({ data }) {
return <div>{/* 复杂渲染逻辑 */}</div>;
}
实际影响有多大?
性能数据
Meta 内部实测,启用 Compiler 后交互响应速度提升最高 2.5×。社区案例中:
- Sanity Studio:标题栏重渲染减少 98%
- Wakelet:列表滚动性能显著提升,无需手动
React.memo
开发体验变化
最重要的一点:心智负担的降低。
过去每个 React 开发者都要背诵「什么时候用 useMemo、什么时候用 useCallback、memo 为什么没生效、依赖数组写错了没」——这些担心现在可以放下了。
写 React 不再是「写好代码 + 猜性能问题」,而是「写好代码,编译器帮你兜底」。
迁移路径
现有项目 → 升级 React 19+ → 安装 babel-plugin-react-compiler
→ 启用 lint 规则 → 逐模块启用 compiler → 移除手动 useMemo/useCallback
新项目 → 从模板(Next.js 16/Vite/Expo)开始 → 默认启用 compiler
潜在问题与注意事项
⚠️ 你也需要知道编译器不完美的地方
- 构建时间增加——编译分析有成本,大型项目可能增加 10-20% 的构建时间
- 调试难度上升——你写的源码和实际运行的优化代码不一致,sourcemap 变得更重要
- 部分模式不兼容——
eval()、new Function()、动态require()会触发 bail-out - 需要 React 19+——若项目仍在使用 React 17/18,需要先升级
- 编译器不是万能药——错误的组件设计(如过大的组件、不合理的状态提升)编译器也救不了
2026 年的 React 开发新常态
站在 2026 年,React 开发生态的基本面已经改变:
- 新建项目默认启用 Compiler——Next.js 16、Vite + React 模板、Expo SDK 都已内置
- lint 规则常态化——
eslint-plugin-react-hooks会在你写出不需要的 memoization 时给出 warning - 渐进式迁移——现有项目逐个文件、逐个模块迁移,用
"use no memo"指令精确保留需要手动优化的模块 - 编译器持续演进——React 团队已有 roadmap 支持更复杂的优化(如自动 code splitting 等)
💡 核心观点:React Compiler 的落地,和 TypeScript 从「可选」变成「标配」是同一个逻辑——工具替代人工,让开发者专注于业务逻辑而非性能微调。懂原理仍然重要,但日常不再需要手动操心。
参考链接:
