过去几年写 React,性能优化几乎是"肌肉记忆":包一层 useMemo、套一个 useCallback、给列表加 key、拆组件减少重渲染。这些优化不是不需要,而是太琐碎——大量样板代码、容易写错、还会因为依赖数组遗漏引入 bug。

React Compiler 的出现,让这一切变成了历史。2026 年,React 19 + React Compiler 已经是生产环境的主流组合,编译器替你做 memoization,开发者回归"写逻辑"本身。本文讲清楚它的原理、怎么迁移、以及实战中的坑。

React Compiler 是什么:编译器替你记住

React Compiler 是一个编译期优化工具,它在构建时分析你的组件,自动判断哪些计算和渲染结果可以被缓存、哪些依赖变了才需要重算。你不再需要手动写 useMemouseCallbackmemo——编译器根据数据的变化自动决策。

它的核心思路是"自动 memoization":

  • 没有手动 useMemoexpensiveCalc(),编译器会自动缓存,只有依赖变了才重算;
  • 没有 useCallback 包裹的函数,编译器会自动稳定引用,避免子组件无谓重渲染;
  • 甚至连组件本身的渲染结果,编译器也会根据 props 的深度比较自动决定是否复用。

收益是双重的:代码更干净(删掉大量样板),性能更稳定(不再依赖开发者手动判断缓存边界)。

它不是魔法:编译器的判断依据

React Compiler 能自动优化,前提是你的代码遵循 React 的"纯函数"约定:相同输入产生相同输出、无副作用。编译器通过静态分析追踪数据依赖,当它发现某个计算的输入没有变化,就跳过重算。

这意味着不纯的代码会破坏优化。比如在渲染期间直接修改外部变量、用 Math.random() 作为渲染输入、在组件顶层调用会改变状态的函数——这些都会让编译器无法安全缓存,退化为正常重渲染(不会报错,只是不优化)。

实战中,只要你遵守"渲染函数是纯函数"这条 React 基本原则,Compiler 就能正常工作。

React 19 的其他重要特性

React Compiler 是性能层面的重头戏,React 19 本身也带来了一批实用能力:

Actions 与表单处理

React 19 引入 Actions 概念,把"提交表单"这类异步动作变成一等公民。以前要手写 isPendinguseEffect 处理提交状态,现在用 useActionStateuseFormStatus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function UpdateName() {
const [name, setName] = useState('')
const [error, submitAction, isPending] = useActionState(
async (previousState, formData) => {
const error = await updateName(formData.get('name'))
if (error) return error
redirect('/path')
}
)
return (
<form action={submitAction}>
<input name="name" />
<button disabled={isPending}>{isPending ? '提交中' : '提交'}</button>
{error && <p>{error}</p>}
</form>
)
}

pending 状态、错误处理、乐观更新都有了官方范式。

use() Hook:直接消费 Promise 和 Context

use() 是 React 19 最灵活的新 Hook,它可以在渲染期间直接读取 Promise(配合 Suspense)或 Context,不需要条件调用 Hook:

1
2
3
4
function Comments({ commentsPromise }) {
const comments = use(commentsPromise) // 直接 await Promise
return comments.map(c => <li key={c.id}>{c.text}</li>)
}

文档元数据与资源管理

titlemetalink 标签可以直接写在组件 JSX 里,React 自动把它们提升到 <head>;脚本、样式表、字体也有官方的预加载和管理 API,不再需要第三方库。

迁移路径:渐进启用

React Compiler 不是"全有或全无",可以按目录渐进启用。官方推荐的迁移步骤:

  1. 先跑 codemodnpx react-compiler-codemod 自动移除不必要的 useMemo/useCallback
  2. 小范围启用:在某个组件目录开启 Compiler,观察行为是否一致;
  3. 全量启用:确认无回归后,对整个项目开启。

Vite 项目通过 babel-plugin-react-compiler 启用,Next.js 则在 next.config.js 里开启 reactCompiler: true

实战中的注意点

  1. 不要混用手动 memo 和 Compiler:开了 Compiler 之后,手写的 useMemo 反而可能干扰编译器的判断。最佳实践是全部删掉,让编译器接管。
  2. 关注"纯函数"约束:渲染期间有副作用的代码要移出。这其实是 React 一直以来的要求,只是 Compiler 把它从"建议"变成了"影响优化的硬约束"。
  3. DevTools 看效果:React DevTools 会显示组件是否被 Compiler 优化、重渲染的原因,排查性能问题更直观。
  4. 不要过度优化状态:Compiler 处理的是"计算",但状态更新仍然会触发重渲染。该拆状态、该用 useReducer 合并的,还是要做。

和已有的"手搓优化"对比

场景 手动优化 React Compiler
昂贵计算缓存 useMemo 自动缓存
函数引用稳定 useCallback 自动稳定
子组件跳过渲染 React.memo 自动判断
代码量 多样板 大幅减少
依赖遗漏风险

小结

React 19 + Compiler 的核心价值是把性能优化从"开发者的责任"变成"编译器的责任"。开发者不再需要纠结"这里要不要 useMemo",回归写业务逻辑本身。2026 年新项目默认启用 Compiler 已是行业惯例,老项目也建议按目录逐步迁移。

如果你对 React 生态的全栈能力感兴趣,可以接着看《Next.js 15 与边缘计算:Server Components 生产实战》。