React 编译器 v1.0
2025年10月7日,由Lauren Tan、Joe Savona和Mofei Zhang撰写。
🌐 Oct 7, 2025 by Lauren Tan, Joe Savona, and Mofei Zhang.
React 团队很高兴分享新的更新:
🌐 The React team is excited to share new updates:
- React 编译器 1.0 今天可用。
- 由编译器提供支持的 lint 规则包含在
eslint-plugin-react-hooks的recommended和recommended-latest预设中。 - 我们发布了一个渐进式采用指南,并与 Expo、Vite 和 Next.js 合作,以便新应用可以在启用编译器的情况下启动。
我们今天发布编译器的第一个稳定版本。React 编译器适用于 React 和 React Native,并且能够自动优化组件和钩子,无需重写。该编译器已在 Meta 的主要应用中经过严格测试,并且完全可以投入生产使用。
🌐 We are releasing the compiler’s first stable release today. React Compiler works on both React and React Native, and automatically optimizes components and hooks without requiring rewrites. The compiler has been battle tested on major apps at Meta and is fully production-ready.
React 编译器 是一个构建时工具,通过自动记忆化优化你的 React 应用。去年,我们发布了 React 编译器的第一个测试版,并收到了很多很棒的反馈和贡献。我们对于采用该编译器的用户所取得的成果感到非常兴奋(参见Sanity Studio 和 Wakelet 的案例研究),并且很高兴将该编译器带给更多 React 社区的用户。
此次发布是一个庞大而复杂的工程努力的成果,这项工作历时近十年。React 团队首次探索编译器始于 2017 年的 Prepack。虽然该项目最终被关闭,但团队从中获得了许多经验,这些经验为 Hooks 的设计提供了参考,而 Hooks 的设计正是考虑到未来的编译器。在 2021 年,Xuan Huang 演示了 React 编译器新设计的 第一次迭代。
🌐 This release is the culmination of a huge and complex engineering effort spanning almost a decade. The React team’s first exploration into compilers started with Prepack in 2017. While this project was eventually shut down, there were many learnings that informed the team on the design of Hooks, which were designed with a future compiler in mind. In 2021, Xuan Huang demoed the first iteration of a new take on React Compiler.
尽管这个新 React 编译器的第一个版本最终被重写,但第一个原型让我们更加确信这是一个可解决的问题,并且让我们了解到,另一种编译器架构可以精确地提供我们所需要的记忆化特性。Joe Savona、Sathya Gunasekaran、Mofei Zhang 和 Lauren Tan 共同完成了我们的第一次重写,将编译器的架构移入基于控制流图(CFG)的高级中间表示(HIR)。这为在 React 编译器中进行更精确的分析甚至类型推断铺平了道路。从那时起,编译器的许多重要部分都被重新编写,每次重写都借鉴了我们从前一次尝试中学到的经验。同时,我们在这个过程中也得到了 React 团队 许多成员的重大帮助和贡献。
🌐 Although this first version of the new React Compiler was eventually rewritten, the first prototype gave us increased confidence that this was a tractable problem, and the learnings that an alternative compiler architecture could precisely give us the memoization characteristics we wanted. Joe Savona, Sathya Gunasekaran, Mofei Zhang, and Lauren Tan worked through our first rewrite, moving the compiler’s architecture into a Control Flow Graph (CFG) based High-Level Intermediate Representation (HIR). This paved the way for much more precise analysis and even type inference within React Compiler. Since then, many significant portions of the compiler have been rewritten, with each rewrite informed by our learnings from the previous attempt. And we have received significant help and contributions from many members of the React team along the way.
这个稳定版本是我们众多版本中的第一个。编译器将继续发展和改进,我们预计它将成为未来十年及更长时间 React 的新基础和新纪元。
🌐 This stable release is our first of many. The compiler will continue to evolve and improve, and we expect to see it become a new foundation and era for the next decade and more of React.
你可以直接跳转到 快速上手,或者继续阅读 React Conf 2025 的亮点内容。
🌐 You can jump straight to the quickstart, or read on for the highlights from React Conf 2025.
深入研究
🌐 How does React Compiler work?
React 编译器是一个优化编译器,通过自动记忆化对组件和钩子进行优化。虽然它目前是作为 Babel 插件实现的,但该编译器在很大程度上与 Babel 解耦,并将 Babel 提供的抽象语法树(AST)转换为自己新颖的高阶中间表示(HIR),并通过多次编译器遍历,仔细理解 React 代码的数据流和可变性。这使编译器能够对渲染中使用的值进行细粒度记忆化,包括条件性记忆化的能力,这是手动记忆化无法实现的。
🌐 React Compiler is an optimizing compiler that optimizes components and hooks through automatic memoization. While it is implemented as a Babel plugin currently, the compiler is largely decoupled from Babel and lowers the Abstract Syntax Tree (AST) provided by Babel into its own novel HIR, and through multiple compiler passes, carefully understands data-flow and mutability of your React code. This allows the compiler to granularly memoize values used in rendering, including the ability to memoize conditionally, which is not possible through manual memoization.
import { use } from 'react';
export default function ThemeProvider(props) {
if (!props.children) {
return null;
}
// The compiler can still memoize code after a conditional return
const theme = mergeTheme(props.theme, use(ThemeContext));
return (
<ThemeContext value={theme}>
{props.children}
</ThemeContext>
);
}See this example in the React Compiler Playground
除了自动记忆化外,React 编译器还对你的 React 代码运行验证过程。这些过程编码了React 规则,并利用编译器对数据流和可变性的理解,在违反 React 规则的地方提供诊断。这些诊断通常会暴露隐藏在 React 代码中的潜在错误,主要通过 eslint-plugin-react-hooks 显示出来。
🌐 In addition to automatic memoization, React Compiler also has validation passes that run on your React code. These passes encode the Rules of React, and uses the compiler’s understanding of data-flow and mutability to provide diagnostics where the Rules of React are broken. These diagnostics often expose latent bugs hiding in React code, and are primarily surfaced through eslint-plugin-react-hooks.
要了解更多关于编译器如何优化你的代码的信息,请访问 Playground。
🌐 To learn more about how the compiler optimizes your code, visit the Playground.
今天使用 React 编译器
🌐 Use React Compiler Today
安装编译器:
🌐 To install the compiler:
npm
npm install --save-dev --save-exact babel-plugin-react-compiler@latestpnpm
pnpm add --save-dev --save-exact babel-plugin-react-compiler@latestyarn
yarn add --dev --exact babel-plugin-react-compiler@latest作为稳定版本的一部分,我们一直在使 React 编译器更容易添加到你的项目中,并对编译器生成的记忆优化进行了改进。React 编译器现在支持将可选链和数组索引作为依赖。这些改进最终会减少重新渲染次数,并使用户界面更具响应性,同时让你继续编写符合惯用习惯的声明性代码。
🌐 As part of the stable release, we’ve been making React Compiler easier to add to your projects and added optimizations to how the compiler generates memoization. React Compiler now supports optional chains and array indices as dependencies. These improvements ultimately result in fewer re-renders and more responsive UIs, while letting you keep writing idiomatic declarative code.
你可以在 我们的文档 中找到关于使用编译器的更多详细信息。
🌐 You can find more details on using the Compiler in our docs.
我们在生产中看到的情况
🌐 What we’re seeing in production
编译器已经在像 Meta Quest Store 这样的应用中发布。我们观察到初始加载和跨页面导航的速度提高了最多 12%,而某些交互速度提升超过 2.5 倍。即使有这些提升,内存使用量仍保持不变。尽管具体效果可能因情况而异,我们建议在你的应用中尝试使用该编译器,以观察类似的性能提升。
向后兼容性
🌐 Backwards Compatibility
如在 Beta 公告中所述,React 编译器兼容 React 17 及更高版本。如果你尚未使用 React 19,可以通过在编译器配置中指定最低目标,并将 react-compiler-runtime 添加为依赖来使用 React 编译器。你可以在这里找到文档 这里。
🌐 As noted in the Beta announcement, React Compiler is compatible with React 17 and up. If you are not yet on React 19, you can use React Compiler by specifying a minimum target in your compiler config, and adding react-compiler-runtime as a dependency. You can find docs on this here.
通过编译器驱动的代码检查执行 React 规则
🌐 Enforce the Rules of React with compiler-powered linting
React 编译器包含一个 ESLint 规则,可帮助识别违反 React 规则 的代码。该 linter 不需要安装编译器,因此升级 eslint-plugin-react-hooks 没有风险。我们建议每个人今天都升级。
🌐 React Compiler includes an ESLint rule that helps identify code that breaks the Rules of React. The linter does not require the compiler to be installed, so there’s no risk in upgrading eslint-plugin-react-hooks. We recommend everyone upgrade today.
如果你已经安装了 eslint-plugin-react-compiler,你现在可以将其移除并使用 eslint-plugin-react-hooks@latest。非常感谢 @michaelfaith 为这一改进做出的贡献!
🌐 If you have already installed eslint-plugin-react-compiler, you can now remove it and use eslint-plugin-react-hooks@latest. Many thanks to @michaelfaith for contributing to this improvement!
安装方法:
🌐 To install:
npm
npm install --save-dev eslint-plugin-react-hooks@latestpnpm
pnpm add --save-dev eslint-plugin-react-hooks@latestyarn
yarn add --dev eslint-plugin-react-hooks@latest// eslint.config.js (Flat Config)
import reactHooks from 'eslint-plugin-react-hooks';
import { defineConfig } from 'eslint/config';
export default defineConfig([
reactHooks.configs.flat.recommended,
]);// eslintrc.json (Legacy Config)
{
"extends": ["plugin:react-hooks/recommended"],
// ...
}要启用 React 编译器规则,我们建议使用 recommended 预设。你也可以查看 README 获取更多说明。以下是我们在 React 大会上展示的一些示例:
🌐 To enable React Compiler rules, we recommend using the recommended preset. You can also check out the README for more instructions. Here are a few examples we featured at React Conf:
- 使用
set-state-in-render捕获会导致渲染循环的setState模式。 - 通过
set-state-in-effect标记 After Effects 中的高成本工作。 - 使用
refs防止在渲染期间不安全的 ref 访问。
我应该如何处理 useMemo、useCallback 和 React.memo?
🌐 What should I do about useMemo, useCallback, and React.memo?
默认情况下,React 编译器会根据其分析和启发式方法对你的代码进行记忆化。在大多数情况下,这种记忆化的精确度将与你可能写的代码一样高,甚至更高——如上所述,编译器甚至可以在 useMemo/useCallback 无法使用的情况下进行记忆化,例如在提前返回之后。
🌐 By default, React Compiler will memoize your code based on its analysis and heuristics. In most cases, this memoization will be as precise, or moreso, than what you may have written — and as noted above, the compiler can memoize even in cases where useMemo/useCallback cannot be used, such as after an early return.
然而,在某些情况下,开发者可能需要对记忆化拥有更多的控制。useMemo 和 useCallback 钩子可以继续与 React 编译器一起使用,作为一种应急手段来控制哪些值被记忆化。一个常见的使用场景是,如果一个记忆化的值被用作副作用的依赖,以确保即使其依赖没有实质性变化,副作用也不会重复触发。
🌐 However, in some cases developers may need more control over memoization. The useMemo and useCallback hooks can continue to be used with React Compiler as an escape hatch to provide control over which values are memoized. A common use-case for this is if a memoized value is used as an effect dependency, in order to ensure that an effect does not fire repeatedly even when its dependencies do not meaningfully change.
对于新代码,我们建议依赖编译器进行记忆化,并在需要时使用 useMemo/useCallback 以实现精确控制。
🌐 For new code, we recommend relying on the compiler for memoization and using useMemo/useCallback where needed to achieve precise control.
对于现有代码,我们建议要么保持现有的记忆化(移除它可能会改变编译结果),要么在移除记忆化之前仔细测试。
🌐 For existing code, we recommend either leaving existing memoization in place (removing it can change compilation output) or carefully testing before removing the memoization.
新的应用应该使用 React 编译器
🌐 New apps should use React Compiler
我们已经与 Expo、Vite 和 Next.js 团队合作,将编译器添加到新的应用体验中。
🌐 We have partnered with the Expo, Vite, and Next.js teams to add the compiler to the new app experience.
Expo SDK 54 及以上版本默认启用编译器,因此新应用将能够从一开始就自动利用编译器的优势。
npx create-expo-app@latestVite 和 Next.js 用户可以在 create-vite 和 create-next-app 中选择启用编译器的模板。
npm create vite@latestnpx create-next-app@latest逐步采用 React 编译器
🌐 Adopt React Compiler incrementally
如果你正在维护现有应用,你可以按自己的节奏推出编译器。我们发布了一份逐步的渐进式采用指南,涵盖了分阶段策略、兼容性检查和部署工具,因此你可以自信地启用编译器。
🌐 If you’re maintaining an existing application, you can roll out the compiler at your own pace. We published a step-by-step incremental adoption guide that covers gating strategies, compatibility checks, and rollout tooling so you can enable the compiler with confidence.
swc 支持(实验性)
🌐 swc support (experimental)
React 编译器可以安装在多个构建工具上,例如 Babel、Vite 和 Rsbuild。
🌐 React Compiler can be installed across several build tools such as Babel, Vite, and Rsbuild.
除了这些工具之外,我们还一直与 swc 团队的 Kang Dongyoon (@kdy1dev) 合作,增加作为 swc 插件的 React 编译器的额外支持。虽然这项工作尚未完成,但在 在你的 Next.js 应用中启用 React 编译器 时,Next.js 的构建性能现在应该会明显更快。
🌐 In addition to those tools, we have been collaborating with Kang Dongyoon (@kdy1dev) from the swc team on adding additional support for React Compiler as an swc plugin. While this work isn’t done, Next.js build performance should now be considerably faster when the React Compiler is enabled in your Next.js app.
我们建议使用 Next.js 15.3.1 或更高版本以获得最佳构建性能。
🌐 We recommend using Next.js 15.3.1 or greater to get the best build performance.
Vite 用户可以继续使用 vite-plugin-react 来启用编译器,通过将其添加为 Babel 插件。我们也在与 oxc 团队合作,添加对编译器的支持。一旦 rolldown 正式发布并且在 Vite 中得到支持,同时 oxc 为 React 编译器添加了支持,我们将更新文档,提供迁移指南。
🌐 Vite users can continue to use vite-plugin-react to enable the compiler, by adding it as a Babel plugin. We are also working with the oxc team to add support for the compiler. Once rolldown is officially released and supported in Vite and oxc support is added for React Compiler, we’ll update the docs with information on how to migrate.
升级 React 编译器
🌐 Upgrading React Compiler
当自动记忆化严格用于性能时,React 编译器的效果最好。编译器的未来版本可能会改变记忆化的应用方式,例如,它可能变得更加细化和精确。
🌐 React Compiler works best when the auto-memoization applied is strictly for performance. Future versions of the compiler may change how memoization is applied, for example it could become more granular and precise.
然而,由于产品代码有时可能以 JavaScript 无法静态检测的方式违反 React 规则,更改记忆化可能偶尔会产生意想不到的结果。例如,先前被记忆化的值可能在组件树中的某个地方被用作 useEffect 的依赖。更改该值的记忆化方式或是否记忆化可能导致该 useEffect 过度或不足触发。虽然我们鼓励 仅将 useEffect 用于同步,但你的代码库可能有 useEffect 用于其他用例,例如仅在特定值改变时需要运行的 effect。
🌐 However, because product code may sometimes break the rules of React in ways that aren’t always statically detectable in JavaScript, changing memoization can occasionally have unexpected results. For example, a previously memoized value might be used as a dependency for a useEffect somewhere in the component tree. Changing how or whether this value is memoized can cause over or under-firing of that useEffect. While we encourage useEffect only for synchronization, your codebase may have useEffects that cover other use cases, such as effects that needs to only run in response to specific values changing.
换句话说,在极少数情况下,更改记忆化可能会导致意外行为。因此,我们建议遵循 React 的规则,并对你的应用进行持续的端到端测试,以便你可以自信地升级编译器,并识别可能引起问题的任何 React 规则违规行为。
🌐 In other words, changing memoization may under rare circumstances cause unexpected behavior. For this reason, we recommend following the Rules of React and employing continuous end-to-end testing of your app so you can upgrade the compiler with confidence and identify any rules of React violations that might cause issues.
如果你的测试覆盖率不高,我们建议将编译器固定到一个确切的版本(例如 1.0.0),而不是使用 SemVer 范围(例如 ^1.0.0)。你可以在升级编译器时,通过传递 --save-exact(npm/pnpm)或 --exact(yarn)标志来实现。然后,你应该手动进行编译器的任何升级,同时注意检查你的应用是否仍能按预期工作。
🌐 If you don’t have good test coverage, we recommend pinning the compiler to an exact version (eg 1.0.0) rather than a SemVer range (eg ^1.0.0). You can do this by passing the --save-exact (npm/pnpm) or --exact flags (yarn) when upgrading the compiler. You should then do any upgrades of the compiler manually, taking care to check that your app still works as expected.
感谢 Jason Bonta、Jimmy Lai、Kang Dongyoon (@kdy1dev) 和 Dan Abramov 审阅和编辑这篇文章。
🌐 Thanks to Jason Bonta, Jimmy Lai, Kang Dongyoon (@kdy1dev), and Dan Abramov for reviewing and editing this post.