メインコンテンツまでスキップ

第89章:React Compiler の未来


1️⃣ ここまでの世界:「メモ化」を手でがんばる時代 🧠

第81〜88章でやってきたこと、ちょっと思い出してみましょう👇

  • 不要な再レンダリングを防ぐために…

    • React.memo(...) でコンポーネントを包む
    • useCallback(...) で関数をメモ化する
    • useMemo(...) で重い計算の結果をメモ化する

みたいな「手作業での最適化」をいっぱい書きましたよね 📝

この章は、そんな世界から

「もう、そういうの、コンパイラが自動でやっとくね〜」

という 新しい世界への入り口 です ✨


2️⃣ React Compiler ってなに?ざっくり一言で 💡

React Compiler は、React チーム公式の

🎯 「ビルド時にあなたのコードを読んで、  安全なところだけ自動でメモ化してくれるツール」

です。

  • ビルド時npm run build とかのタイミング)に動く
  • コンポーネントやフックのコードを解析して
  • useMemo / useCallback / React.memo みたいなことを 自動でいい感じにやってくれる✨(React)

しかも 2025年10月に v1.0 として安定版リリース されていて、 「実験用」から「本番OKなやつ」に昇格しています 🎉(React)


3️⃣ 図でイメージする:どこで動いてるの?🧩

React Compiler は、ブラウザの中ではなくて、 ビルドツール(Vite / Webpack など)の裏側で動きます。

「自分が書くコード」はこれまで通りだけど、 裏でコンパイラが “勝手に賢くしてくれる” というイメージです 😊


4️⃣ 具体的に何をしてくれるの?🧮

公式ドキュメントやブログをざっくりまとめると、React Compiler は:(React)

  • 自動メモ化(Automatic Memoization)

    • 入力(Props や State)が変わらないときは そのコンポーネントを 再レンダリングしない ようにする
  • コンポーネント & フック両方を最適化

    • コンポーネントだけじゃなくて、フックも解析してくれる
  • データの流れと「変更される / されない」を解析

    • 「この値は変わらない」「ここはミューテートしてない」 みたいな情報をもとに、安全にスキップできるか判断する
  • ✅ 「これは危なそう…」なところは あえて最適化しない

    • 無理にいじってバグらせるより、「触らない」を選んでくれる

5️⃣ React 19 と React Compiler の関係 👩‍💻💻

2024〜2025年で React まわりはけっこう大きく変わりました。

  • React 19 系がリリースされて、 新しいデータ取得やフォーム機能、パフォーマンス改善などが入り…
  • その中の “相棒” みたいな位置づけで 🌟 React Compiler が実用レベルに到達 しました。(WEQテクノロジーズ)

さらに今は:

  • Next.js や Expo など、人気フレームワークにも React Compiler のサポートがどんどん入ってきている(Next.js)
  • Vite + React でも、Babel プラグインを入れるだけで 簡単に使えるようになっています 🎯(React)

6️⃣ Before / After:手メモ化 → Compiler 任せの世界 ✂️✨

「実際のコードがどう変わるの?」というイメージを シンプルな例で見てみましょう 👀

🐢 Before:がんばって useMemo / useCallback / React.memo

// UserList.tsx
import { memo, useCallback, useMemo } from "react";

type User = {
id: number;
name: string;
};

type UserListProps = {
users: User[];
onSelect: (id: number) => void;
};

const UserListItem = memo(function UserListItem(props: {
user: User;
onSelect: (id: number) => void;
}) {
const { user, onSelect } = props;

console.log("render:", user.name);

return (
<li>
<button onClick={() => onSelect(user.id)}>{user.name}</button>
</li>
);
});

export function UserList({ users, onSelect }: UserListProps) {
const sortedUsers = useMemo(
() => [...users].sort((a, b) => a.name.localeCompare(b.name)),
[users]
);

const handleSelect = useCallback(
(id: number) => {
onSelect(id);
},
[onSelect]
);

return (
<ul>
{sortedUsers.map((user) => (
<UserListItem
key={user.id}
user={user}
onSelect={handleSelect}
/>
))}
</ul>
);
}

やってることは正しいけど…

  • 型も Props も長い 🥹
  • useMemo / useCallback の依存配列も気にしないといけない
  • ちょっとコードがゴチャっとしますよね。

🐇 After:React Compiler 前提だと、コードは素直でOK

React Compiler を有効化している前提なら、 まずは「読みやすい素直なコード」から書いてOK という世界観になります。(React)

// UserList.tsx
type User = {
id: number;
name: string;
};

type UserListProps = {
users: User[];
onSelect: (id: number) => void;
};

function UserListItem({ user, onSelect }: {
user: User;
onSelect: (id: number) => void;
}) {
console.log("render:", user.name);

return (
<li>
<button onClick={() => onSelect(user.id)}>
{user.name}
</button>
</li>
);
}

export function UserList({ users, onSelect }: UserListProps) {
// いったん「素直に」書く
const sortedUsers = [...users].sort((a, b) =>
a.name.localeCompare(b.name)
);

return (
<ul>
{sortedUsers.map((user) => (
<UserListItem
key={user.id}
user={user}
onSelect={onSelect}
/>
))}
</ul>
);
}

このコードを ビルドするときに React Compiler が解析して

  • どこをメモ化すればいいか
  • どの再レンダリングをスキップできるか

を自動で判断してくれます 🤖✨

もちろん、本当にめちゃくちゃ重い処理 とかは まだ useMemo を書いた方がわかりやすいケースもありますが、 「とりあえず全部 useCallback で囲んどこう…」みたいな世界からは だいぶ解放されるイメージです 🎉


7️⃣ どうやって有効化するの?(Vite + React + TS の例)⚙️

※ このロードマップでは「概念」をメインにしますが、 「ちょっと試してみたい!」というとき用に、 Vite プロジェクトでのざっくり手順も書いておきます 🧪

① パッケージを入れる

VS Code のターミナルで(WindowsでもOK)👇

npm install -D babel-plugin-react-compiler

公式ドキュメントでも、babel-plugin-react-compilerdevDependency として入れることが推奨されています。(React)

vite.config.ts にプラグインを追加

// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
plugins: [
react({
babel: {
plugins: ["babel-plugin-react-compiler"],
},
}),
],
});

これで、

  • npm run dev → 開発時からコンパイラの動きを試せる
  • npm run build → 本番ビルド時にも最適化が走る

という感じになります 💻✨(React)


8️⃣ まだ「魔法」ではないポイントも大事 ⚠️

React Compiler はかなりすごいんですが、 何でもかんでも自動で最適にしてくれる“魔法”ではない です。

🔎 コンパイラが前提にしているルール

公式ブログなどでも、React Compiler が安全に動くためには、 React のルールを守って書かれていることが前提 だと説明されています。(React)

たとえば:

  • propsstate直接書き換えない(イミュータブルに扱う)
  • コンポーネントは 同じ入力なら同じ出力(副作用のない純粋な関数)
  • Hooks のルール(呼び出す順番を変えない etc.)を守る

これらをちゃんと守っているからこそ、

「このコンポーネントは入力が変わらないなら  結果も変わらないはずだから、再レンダリングいらないよね」

コンパイラが自信を持って判断できる んですね ✨

🔦 どうしても困ったときの「オフスイッチ」

逆に、「この関数は今は最適化してほしくない!」 というときのために、

  • "use no memo" というディレクティブで その関数だけコンパイラから除外する 機能も用意されています。(React)

9️⃣ いまの私たちの立ち位置:どう意識しておけばいい?🧭

このロードマップの学習者的には、こんな感じで考えておくとラクです👇

  1. まずは「ふつうにきれいな React コード」を書く力をつける

    • State や Props の基本
    • イミュータブルな更新
    • Hooks のルール → これが コンパイラが活躍できる土台 💪
  2. パフォーマンス最適化の「考え方」は学んでおく

    • 「なぜ再レンダリングが問題になるのか」
    • 「どこがボトルネックになりやすいか」 → これは React Compiler 時代でも超重要
  3. 実務では、

    • まずは素直なコードを書く
    • 必要に応じて React Compiler を導入
    • それでも足りなければ useMemo / useCallback などを ピンポイントで 追加

という流れが主流になっていきそうです 🌈


🔟 さらに安心材料:ESLint プラグインもあるよ ✅

React Compiler には ESLint プラグイン もあって、

  • コンパイラをまだ使っていなくても
  • 「React のルールを破ってないか?」をチェックしてくれる

という使い方ができます。 React チームも「全員使ってほしい」とおすすめしているので、 実案件ではかなり心強い相棒になりそうです 💪(React)


まとめ 🎀

この章で押さえておきたいポイントはこれ👇

  • React Compiler は ビルド時に動く「自動メモ化コンパイラ」 🤖

  • useMemo / useCallback / React.memo の多くを 裏側で肩代わり してくれるようになる ✨

  • でも、

    • イミュータブルな更新
    • Hooks のルール
    • 純粋なコンポーネント設計 といった 基礎力がないとコンパイラも本気を出せない
  • Vite + React + TS でも、Babel プラグインを足すだけで 比較的カンタンに試せる 🛠️

  • これからの React は

    「まずはきれいで素直なコードを書く → あとはコンパイラと一緒に最適化していく」 という時代になっていきます 🚀


チェックタイム ✏️(軽く答えを考えてみてね)

Q1. React Compiler は「いつ」動くツールでしょう? Q2. React Compiler が特に自動化してくれるのはどんな処理? Q3. React Compiler にとってうれしい「書き方のルール」を 2 つ思い出してみてください。

(例:state を直接書き換えない、Hooks のルールを守る、など)


この章では「未来の React の姿」をちらっと覗きました 👀✨ 次の章では、「メモ化はあくまで最適化テクニックであって、 まずは正しく動くものを作るのが大事だよね」という話に続いていきます 💖