前言
在 React Conf 2024,React Complier 终于开源了,第一次亮相是在 React Conf 2021,那时还叫做 React Forget,是黄玄做的一次 sharing - React without memo
在黄玄加入字节之后,Ask me anything 内部分享,大家最关心的除了恋综后续,还有就是 React Forgot 的后续,那时黄玄提到,实际上在 Meta 内部,React Forget 实际上已经在 Instagram 等业务完成落地,另外 React 19 在 Meta 内部早已落地,并且在快速推进。在 Meta 公司与国内大厂有一些区别,在 Meta 内部全公司只有一个 monorepo,所以在推进 React 升级上比较好做,只需要由基础架构 Infra 团队完成版本升级即可。
Complier 是什么
React 的更新机制是,任何一个组件发生 state 状态的变更,React 都会从最顶层的根节点开始往下递归对比,通过双缓存机制判断出哪些节点发生了变化,然后更新节点。Re-render 的现象是很普遍的,不过 React 也提供了方式进行手动 Memo 优化。
在 Complier 出现之前,React 并没有一个 tokenize 的概念,Complier 实际上赋予了 React 编程语言的能力,React Team 基于 React Complier 实现了 memo 的自动优化。实现上是通过 Babel 插件的方式,自动增加 memo tag
Savona:React Compiler 更像 TypeScript,或者 JavaScript 引擎中的编译器,比如 V8 或 Hermes,”他说到。“它将我们的代码分解成单独的表达式,并构建一个控制流和数据流图。它执行复杂的优化,如死代码消除、常量传播、类型推断,甚至别名分析等等。这些优化通常会出现在 JavaScript 引擎或 Rust 或 C++ 等语言的编译器中。
如何使用
健康检查
首先可以执行 healthcheck 来检查能够优化多少个组件
npx react-compiler-healthcheck@latest
ESlint 插件接入
这个命令执行之后会显示现在有多少个组件在引入 React Complier 之后可以被自动优化
npm install eslint-plugin-react-compiler
也提供了 ESlint 插件进行优化检测
babel 插件
前提需要满足 React 版本 >=19,安装 babel-plugin-react-compiler 插件
npm install babel-plugin-react-compiler
引入 babel 插件
// babel.config.js
const ReactCompilerConfig = { /* ... */ };
module.exports = function () {
return {
plugins: [
['babel-plugin-react-compiler', ReactCompilerConfig], // must run first!
// ...
],
};
};
当 React 代码被 Complier 编译过之后,会变成右侧的样子,自动引入 useMemoCache 函数
当前 React Complier 只能运行在 React 19 RC 版本上,但是针对低版本,React 官网也提供了 polyfill 的方式
可以在 React devtools 5+ 版本查看优化效果
当前落地效果
目前在 Meta instagram 和 Quest 商店等大型 App 已完成落地,编译器优化版本的速度是以前的两倍多。初始加载时间和跨页面导航时间提高了 12%。而且对内存使用率或整体崩溃情况都没有影响,这可以通过内存不足的错误反映出来。导航任务加载速度至少提高了 4%。Instagram 在每条路线上平均提高了 3%。
对于 ins 这种类型的 app 来说,在一个特定的页面上,即便指标上提高 1 或 2 个百分点,也是一个很不错的优化
业务接入
对于 Webpack / Vite 接入的项目,可以在 React 19 正式版上线之后开始接入,但是 Complier 的稳定性还需要社区进一步观察,我的看法是先观察一段时间,如果项目历史包袱比较轻,能升到 19 版本,可以考虑接入
总结
React Complier 技术很有意义,在于他是对使用者无感的,即便对于开发者也不是破坏性改动,虽然原理极其复杂,但作为开发者我们只需要关注如何引入消费即可。