配了三年 React,每次写组件第一件事就是想「这里要不要 useMemo」——今天这件事被 React Compiler 彻底自动化了
配了三年 React,每次写组件第一件事就是想「这里要不要 useMemo」——今天这件事被 React Compiler 彻底自动化了
React 团队在 2019 年推 Hooks 的时候,大概没想到「什么时候该用 useMemo」会成为 React 开发者最常见的焦虑来源。
到 2026 年,这个问题的答案终于变了:不用想了,让编译器来。
React 19 自带的编译器(原名 React Forget,正式名就是 React Compiler)正式稳定了。它的工作方式很直接:分析你的代码,在构建时自动插入 memoization,不需要你手动调用任何 Hook。
数据说话:
React 团队内部测试,典型 CRUD 看板应用开启编译器后,渲染时间降低 20-40%。生产环境的实测数据更激进——某团队三个代码库测试,复杂表格 UI 的不必要重渲染减少 35-60%;有团队直接删除了代码库里 ~70% 的 useMemo/useCallback 调用。
效果来自两个方面:一是编译器比你更准确地判断「这个值稳定了吗」;二是避免了手写 memoization 时常见的依赖遗漏 bug——那才是真正拖慢页面的根子。
它怎么做到的?
编译器对 JSX 和 JavaScript 做静态分析,理解哪些值在两次渲染之间稳定、哪些会变,然后在输出代码里直接跳过无需重新渲染的分支。整个过程在构建时完成,不增加运行时开销。
关键前提:代码必须严格遵守 React 规则。 编译器像是一个带牙齿的 linter——如果代码在 Hook 调用顺序、副作用处理等方面违反了 React 语义规范,编译器会直接跳过那块代码的优化,不报错,只是不优化。这反而是好事:它逼着你先把代码写对。
// 以前:想 memoization 要写三层嵌套
const ExpensiveList = React.memo(({ items, onSelect }) => {
const sortedItems = useMemo(
() => [...items].sort((a, b) => a.name.localeCompare(b.name)),
[items]
);
const handleSelect = useCallback((id) => onSelect(id), [onSelect]);
return (
<ul>
{sortedItems.map(item => (
<li key={item.id} onClick={() => handleSelect(item.id)}>
{item.name}
</li>
))}
</ul>
);
});
// React 19 编译器:写自然代码,编译器处理优化
function ExpensiveList({ items, onSelect }) {
const sortedItems = [...items].sort((a, b) => a.name.localeCompare(b.name));
return (
<ul>
{sortedItems.map(item => (
<li key={item.id} onClick={() => onSelect(item.id)}>
{item.name}
</li>
))}
</ul>
);
}
迁移路径:
第一步:npm install babel-plugin-react-compiler 然后配置 babel 插件 target 为 19,不改任何业务代码,先跑一遍看有没有违规。这个阶段编译器会输出哪些文件它优化了、哪些跳过了。
第二步:处理违规代码。常见的是 render 函数里有副作用——这本来就是不对的 React 模式,编译器只是在帮你发现它。
第三步:删掉 useMemo/useCallback/React.memo,逐个验证行为不变。生产经验是大多数删除不会有可见差异——编译器已经在构建时处理了。
和 React 19 其他变化的关系:
React 19 还移除了 string refs、propTypes、forwardRef 这些废弃 API,forwardRef 迁移时正好配合编译器一起做。另外,React Compiler 优化的是客户端组件渲染性能,不影响 React Server Components——RSC 的优势是零客户端 JS,两者从不同维度解决性能问题。
这意味着什么:
React 开发者的认知负担减了一截。「这个值需不需要 memo」不再是每写一个组件都要想的问题。你可以用更自然的顺序写代码,需要优化的时候编译器会处理。
React 19 是自 2018 年 Hooks 以来最改变写代码方式的版本。编译器是其中最关键的那一件。
下一步行动清单:
npm install react@19 react-dom@19升级依赖npm install babel-plugin-react-compiler安装编译器插件- 配置 babel,target 设为 19,先跑一遍看哪些文件被跳过
- 修复违规代码(主要是 render 里的副作用)
- 逐个删除 useMemo/useCallback,验证行为不变
- 有 Next.js 15 项目?编译器已内置,只要
experimental.reactCompiler: true即可
评论区
登录后可评论。