CJH_BLOG

React Compiler 正式落地,我们真的可以告别 useMemo 了吗?

C
cjh
·2026年06月03日·👁 6 次阅读

一句话总结: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 上首次以实验性功能公开亮相。

时间事件
2018Meta 内部启动「React Forget」项目
2024.05React Conf 公开亮相,更名为 React Compiler
2025 Q1进入 RC 阶段
2025.10v1.0 稳定版发布,内置 eslint 规则和迁移指南
2025 Q4Next.js 16 稳定支持
2026Vite、Expo 全面内置,编译器成为新建项目的默认选项

2025 年 10 月 7 日是真正值得标记的一天。React 团队在官方博客宣布 Compiler v1.0 稳定版,并同时发布了:

  • 内置 lint 规则——eslint-plugin-react-hooksrecommended 预设中包含了 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)
  • 追踪依赖关系图——包括可选链、数组索引等复杂场景
  • 生成编译后的优化代码,等价于手动插入了 useMemouseCallbackReact.memo

你可以把编译器想象成一个 自动帮你写完 useMemo 的机器人,而且它不会犯「漏了依赖」或「写了多余依赖」这种人类常犯的错误。

「告别」不是「抹掉」

这里有一个关键的认识误区。React Compiler 并没有删除 useMemouseCallback 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 开发生态的基本面已经改变:

  1. 新建项目默认启用 Compiler——Next.js 16、Vite + React 模板、Expo SDK 都已内置
  2. lint 规则常态化——eslint-plugin-react-hooks 会在你写出不需要的 memoization 时给出 warning
  3. 渐进式迁移——现有项目逐个文件、逐个模块迁移,用 "use no memo" 指令精确保留需要手动优化的模块
  4. 编译器持续演进——React 团队已有 roadmap 支持更复杂的优化(如自动 code splitting 等)

💡 核心观点:React Compiler 的落地,和 TypeScript 从「可选」变成「标配」是同一个逻辑——工具替代人工,让开发者专注于业务逻辑而非性能微调。懂原理仍然重要,但日常不再需要手动操心。


参考链接:

登录后可为文章点赞


#评论区

登录 后参与讨论
💬

暂无评论,成为第一个留言的人吧