React Compiler v1.0
2025年10月7日 by Lauren Tan、Joe Savona、Mofei Zhang
Reactチームは新しいアップデートをお知らせできることを嬉しく思います:
- React Compiler 1.0が本日利用可能になりました
- コンパイラ駆動のlintルールが
eslint-plugin-react-hooksのrecommendedおよびrecommended-latestプリセットに同梱されました
- 段階的導入ガイドを公開し、Expo、Vite、Next.jsと提携して新しいアプリがコンパイラを有効にした状態で開始できるようになりました
本日、コンパイラの最初の安定版リリースを公開します。React CompilerはReactとReact Nativeの両方で動作し、書き直しを必要とせずにコンポーネントとhooksを自動的に最適化します。このコンパイラはMetaの主要アプリで実戦テストされており、完全にプロダクション対応です。
React Compilerは、自動メモ化を通じてReactアプリを最適化するビルド時ツールです。昨年、React Compilerの最初のベータ版を公開し、多くの素晴らしいフィードバックと貢献を受けました。コンパイラを採用した方々からの成果(Sanity StudioとWakeletのケーススタディを参照)に興奮しており、Reactコミュニティのより多くのユーザーにコンパイラを提供できることを楽しみにしています。
このリリースは、ほぼ10年にわたる巨大で複雑なエンジニアリング努力の集大成です。Reactチームのコンパイラへの最初の探求は2017年のPrepackから始まりました。このプロジェクトは最終的に終了しましたが、将来のコンパイラを念頭に置いて設計されたHooksの設計についてチームに多くの学びを与えました。
2021年、Xuan HuangがReact Compilerの新しいアプローチの最初の反復をデモしました。この新しいReact Compilerの最初のバージョンは最終的に書き直されましたが、最初のプロトタイプは、これが解決可能な問題であることへの確信を高め、代替コンパイラアーキテクチャが私たちが望むメモ化特性を正確に提供できることを学びました。
Joe Savona、Sathya Gunasekaran、Mofei Zhang、Lauren Tanは最初の書き直しに取り組み、コンパイラのアーキテクチャをControl Flow Graph(CFG)ベースのHigh-Level Intermediate Representation(HIR)に移行しました。これにより、React Compiler内でのより精密な分析と型推論への道が開かれました。
それ以来、コンパイラの多くの重要な部分が書き直され、各書き直しは前回の試みからの学びに基づいて行われました。そして、その過程でReactチームの多くのメンバーから重要な支援と貢献を受けました。
この安定版リリースは多くのリリースの最初のものです。コンパイラは進化と改善を続け、今後10年以上のReactの新しい基盤と時代になることを期待しています。
クイックスタートに直接ジャンプするか、React Conf 2025のハイライトを読み続けてください。
詳細解説
React Compilerはどのように動作するのか?
React Compilerは、自動メモ化を通じてコンポーネントとhooksを最適化する最適化コンパイラです。現在はBabelプラグインとして実装されていますが、コンパイラは主にBabelから分離されており、Babelによって提供されるAbstract Syntax Tree(AST)を独自の新しいHIRに変換し、複数のコンパイラパスを通じて、Reactコードのデータフローと可変性を慎重に理解します。
これにより、コンパイラは手動メモ化では不可能な条件付きメモ化を含め、レンダリングで使用される値を細かくメモ化できます。
import { use } from 'react';
export default function ThemeProvider(props) {
if (!props.children) {
return null;
}
const theme = mergeTheme(props.theme, use(ThemeContext));
return (
<ThemeContext value={theme}>
{props.children}
</ThemeContext>
);
}
この例をReact Compiler Playgroundで見る
自動メモ化に加えて、React CompilerにはReactコードで実行される検証パスもあります。これらのパスはReactのルールをエンコードし、コンパイラのデータフローと可変性の理解を使用して、Reactのルールが破られている箇所で診断を提供します。これらの診断は、Reactコードに隠れている潜在的なバグを露呈することが多く、主にeslint-plugin-react-hooksを通じて表示されます。
コンパイラがコードをどのように最適化するかについて詳しく学ぶには、Playgroundを訪問してください。
今日からReact Compilerを使用する
コンパイラをインストールするには:
npm install --save-dev --save-exact babel-plugin-react-compiler@latest
pnpm add --save-dev --save-exact babel-plugin-react-compiler@latest
yarn add --dev --exact babel-plugin-react-compiler@latest
安定版リリースの一環として、React Compilerをプロジェクトに追加しやすくし、コンパイラがメモ化を生成する方法に最適化を追加しました。React Compilerは現在、オプショナルチェーンと配列インデックスを依存関係としてサポートしています。これらの改善により、最終的により少ない再レンダリングとより応答性の高いUIが実現され、慣用的な宣言的コードを書き続けることができます。
Compilerの使用に関する詳細は、ドキュメントで確認できます。
プロダクションで見られる成果
コンパイラはすでにMeta Quest Storeなどのアプリで出荷されています。初期ロードとページ間ナビゲーションが最大12%改善され、特定のインタラクションは2.5倍以上高速化されています。これらの成果があってもメモリ使用量は中立を保っています。
結果は異なる場合がありますが、同様のパフォーマンス向上を確認するために、アプリでコンパイラを試すことをお勧めします。
後方互換性
ベータ版の発表で述べたように、React CompilerはReact 17以上と互換性があります。まだReact 19を使用していない場合は、コンパイラ設定で最小ターゲットを指定し、react-compiler-runtimeを依存関係として追加することで、React Compilerを使用できます。
これに関するドキュメントはこちらで確認できます。
コンパイラ駆動のlintingでReactのルールを強制する
React Compilerには、Reactのルールを破るコードを特定するのに役立つESLintルールが含まれています。linterはコンパイラのインストールを必要としないため、eslint-plugin-react-hooksをアップグレードするリスクはありません。今日すべての人がアップグレードすることをお勧めします。
すでにeslint-plugin-react-compilerをインストールしている場合は、それを削除してeslint-plugin-react-hooks@latestを使用できます。この改善に貢献してくれた@michaelfaithに感謝します!
インストールするには:
npm install --save-dev eslint-plugin-react-hooks@latest
pnpm add --save-dev eslint-plugin-react-hooks@latest
yarn add --dev eslint-plugin-react-hooks@latest
import reactHooks from 'eslint-plugin-react-hooks';
import { defineConfig } from 'eslint/config';
export default defineConfig([
reactHooks.configs.flat.recommended,
]);
{
"extends": ["plugin:react-hooks/recommended"],
}
React Compilerルールを有効にするには、recommendedプリセットの使用をお勧めします。詳細な手順についてはREADMEも確認してください。
React Confで紹介したいくつかの例:
set-state-in-renderでレンダリングループを引き起こすsetStateパターンをキャッチ
set-state-in-effectでエフェクト内の高コストな作業にフラグを立てる
refsでレンダリング中の安全でないref アクセスを防止
useMemo、useCallback、React.memoについてどうすべきか?
デフォルトでは、React Compilerは分析とヒューリスティックに基づいてコードをメモ化します。ほとんどの場合、このメモ化は書いたものと同じかそれ以上に精密であり、上記で述べたように、コンパイラはuseMemo/useCallbackが使用できない場合(早期returnの後など)でもメモ化できます。
ただし、場合によっては開発者がメモ化をより制御する必要があるかもしれません。useMemoとuseCallbackフックは、どの値をメモ化するかを制御するエスケープハッチとして、React Compilerと一緒に使用し続けることができます。
これの一般的な使用例は、メモ化された値がエフェクトの依存関係として使用される場合で、依存関係が意味的に変更されていない場合でもエフェクトが繰り返し発火しないようにするためです。
新しいコードでは、メモ化にコンパイラに依存し、精密な制御を実現するために必要に応じてuseMemo/useCallbackを使用することをお勧めします。既存のコードでは、既存のメモ化をそのまま残すか(削除するとコンパイル出力が変わる可能性があります)、メモ化を削除する前に慎重にテストすることをお勧めします。
新しいアプリはReact Compilerを使用すべき
Expo、Vite、Next.jsチームと提携して、新しいアプリエクスペリエンスにコンパイラを追加しました。Expo SDK 54以上ではデフォルトでコンパイラが有効になっているため、新しいアプリは最初からコンパイラを自動的に活用できます。
npx create-expo-app@latest
ViteとNext.jsユーザーは、create-viteとcreate-next-appでコンパイラ有効テンプレートを選択できます。
npm create vite@latest
npx create-next-app@latest
React Compilerを段階的に導入する
既存のアプリケーションを維持している場合は、自分のペースでコンパイラを展開できます。ゲーティング戦略、互換性チェック、展開ツールをカバーする段階的導入ガイドを公開したので、自信を持ってコンパイラを有効にできます。
swcサポート(実験的)
React CompilerはBabel、Vite、Rsbuildなどの複数のビルドツールにインストールできます。これらのツールに加えて、swcチームのKang Dongyoon(@kdy1dev)と協力して、React Compilerのswcプラグインとしての追加サポートを追加しています。
この作業は完了していませんが、Next.jsアプリでReact Compilerが有効になっている場合、Next.jsのビルドパフォーマンスが大幅に向上するはずです。最高のビルドパフォーマンスを得るには、Next.js 15.3.1以上の使用をお勧めします。
Viteユーザーは、Babelプラグインとして追加することで、vite-plugin-reactを使用してコンパイラを有効にし続けることができます。
また、oxcチームと協力してコンパイラのサポートを追加しています。rolldownが正式にリリースされてViteでサポートされ、React Compilerのoxcサポートが追加されたら、移行方法に関する情報でドキュメントを更新します。
React Compilerのアップグレード
React Compilerは、適用される自動メモ化が厳密にパフォーマンスのためである場合に最も効果的に動作します。コンパイラの将来のバージョンでは、メモ化の適用方法が変更される可能性があります。例えば、より細かく精密になる可能性があります。
しかし、プロダクトコードがJavaScriptで静的に検出できない方法でReactのルールを破ることがあるため、メモ化を変更すると時々予期しない結果が生じることがあります。例えば、以前にメモ化された値がコンポーネントツリーのどこかでuseEffectの依存関係として使用されている可能性があります。この値がメモ化される方法や有無を変更すると、そのuseEffectの過剰または不足な発火を引き起こす可能性があります。
useEffectは同期のためだけに使用することを推奨していますが、コードベースには特定の値の変更に応じてのみ実行される必要があるエフェクトなど、他の使用例をカバーするuseEffectがある可能性があります。
言い換えると、メモ化を変更すると、まれな状況で予期しない動作を引き起こす可能性があります。このため、Reactのルールに従い、アプリの継続的なエンドツーエンドテストを採用して、自信を持ってコンパイラをアップグレードし、問題を引き起こす可能性のあるReactのルール違反を特定することをお勧めします。
良いテストカバレッジがない場合は、SemVerの範囲(例:^1.0.0)ではなく、コンパイラを正確なバージョン(例:1.0.0)に固定することをお勧めします。これは、コンパイラをアップグレードする際に--save-exact(npm/pnpm)または--exactフラグ(yarn)を渡すことで実行できます。その後、コンパイラのアップグレードを手動で行い、アプリが期待通りに動作することを確認してください。
この投稿をレビューし編集してくれたJason Bonta、Jimmy Lai、Kang Dongyoon(@kdy1dev)、Dan Abramovに感謝します。