React 编译器

了解如何在 Expo 应用中启用和使用 React Compiler。


警告:React Compiler 是实验性的。目前,它处于暂停状态,我们将很快提供有关其使用的更多更新。

新的 React 编译器 会自动记忆组件和钩子以实现细粒度的反应性。这可以显著提高你的应用的性能。React Compiler 目前处于实验阶段,默认情况下未启用。你可以按照以下说明在你的应用中启用它。

¥The new React Compiler automatically memoizes components and hooks to enable fine-grained reactivity. This can lead to significant performance improvements in your app. The React Compiler is currently experimental and is not enabled by default. You can enable it in your app by following the instructions below.

启用 React 编译器

¥Enabling React Compiler

1

Check how compatible your project is with the React Compiler.

Terminal
npx react-compiler-healthcheck@latest

This will generally verify if your app is following the rules of React.

2

Install babel-plugin-react-compiler and the React compiler runtime in your project:

Terminal
npx expo install babel-plugin-react-compiler@beta
Terminal
npx expo install babel-plugin-react-compiler@beta react-compiler-runtime@beta

3

Toggle on the React Compiler experiment in your app config file:

app.json
{
  "experiments": {
    "reactCompiler": true
  }
}

Enabling the linter

In the future, all of the following steps below will be automated by Expo CLI.

Additionally, you should use the ESLint plugin to continuously enforce the rules of React in your project.

1

Run npx expo lint to ensure ESLint is setup in your app, then install the ESLint plugin for React Compiler:

Terminal
npx expo install eslint-plugin-react-compiler

2

Update your ESLint configuration to include the plugin:

.eslintrc.js
// https://expo.nodejs.cn/guides/using-eslint/
const { defineConfig } = require('eslint/config');
const expoConfig = require('eslint-config-expo/flat');

module.exports = defineConfig([
  expoConfig,
  {
    ignores: ['dist/*'],
    plugins: ['react-compiler'],
    rules: {
      'react-compiler/react-compiler': 'error',
    },
  },
]);

Incremental adoption

You can incrementally adopt the React Compiler in your app using a few strategies:

1

Configure the Babel plugin to only run on specific files or components. To do this:

  1. If your project doesn't have babel.config.js, create one by running npx expo customize babel.config.js.
  2. Add the following configuration to babel.config.js:
babel.config.js
module.exports = function (api) {
  api.cache(true);

  return {
    presets: [
      [
        'babel-preset-expo',
        {
          'react-compiler': {
            sources: filename => {
              // Match file names to include in the React Compiler.
              return filename.includes('src/path/to/dir');
            },
          },
        },
      ],
    ],
  };
};

Whenever you change your babel.config.js file, you need to restart the Metro bundler to apply the changes:

Terminal
npx expo start --clear

2

Use the "use no memo" directive to opt out of the React Compiler for specific components or files.

function MyComponent() {
  'use no memo';

  return <Text>Will not be optimized</Text>;
}

Usage

为了更好地了解 React Compiler 的工作原理,请查看 React Playground

¥To better understand how React Compiler works, check out the React Playground.

改进主要是自动的。你可以删除 useCallbackuseMemoReact.memo 的实例以支持自动记忆。类组件不会进行优化。而是迁移到功能组件。

¥Improvements are primarily automatic. You can remove instances of useCallback, useMemo, and React.memo in favor of the automatic memoization. Class components will not be optimized. Instead, migrate to function components.

Expo 的 React Compiler 实现将仅在应用代码(无节点模块)上运行,并且仅在为客户端打包时运行(在服务器渲染中禁用)。

¥Expo's implementation of the React Compiler will only run on application code (no node modules), and only when bundling for the client (disabled in server rendering).

配置

¥Configuration

你可以通过使用 Babel 配置中的 react-compiler 对象将其他设置传递给 React Compiler Babel 插件:

¥You can pass additional settings to the React Compiler Babel plugin by using the react-compiler object in the Babel configuration:

babel.config.js
module.exports = function (api) {
  api.cache(true);

  return {
    presets: [
      [
        'babel-preset-expo',
        {
          'react-compiler': {
            // Passed directly to the React Compiler Babel plugin.
            compilationMode: 'strict',
            panicThreshold: 'all_errors',
          },
          web: {
            'react-compiler': {
              // Web-only settings...
            },
          },
        },
      ],
    ],
  };
};