logo

Nextjs で React Compilerを導入してみる

2025-11-22
a month ago

開発環境

  • next 16.0.3
  • react 19.2.0
  • react-dom 19.2.0

前提

  • Next.js プロジェクトは作成済み
  • yarn を利用したパッケージ管理を前提
  • React Compiler を Next.js 側で有効化して自動メモ化の挙動を確認します

本題

1. React Compiler の導入と設定

Next.js では next.config.tsreactCompiler: true を追加するだけで導入できます。

import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  reactCompiler: true,
};

export default nextConfig;

ビルド時に、React Compiler がコンポーネント単位で自動メモ化(Automatic Memoization)を行い、不要な再レンダーを抑えてくれます。

2. お試し用の実装

React Compiler の有効性を確認するため、状態更新が発生しても「重い計算処理」を再実行しないかどうかを確認するサンプルを作成します。

import { Card } from './_components/card';

export default function Home() {
  return (
    <div className="flex min-h-screen items-center justify-center bg-black">
      <main className="flex min-h-screen w-full max-w-3xl flex-col items-center justify-center py-32 px-16 gap-8">
        <div className="space-y-2">
          <h1 className="text-3xl font-bold text-zinc-50">
            React Compiler Demo
          </h1>
          <p className="text-zinc-400">
            Interact with the component below to verify React Compiler
            optimization
          </p>
        </div>
        <Card />
      </main>
    </div>
  );
}
'use client';

import { useState } from 'react';

export const Card = () => {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  const handleIncrement = () => {
    setCount(count + 1);
  };

  const handleReset = () => {
    setCount(0);
    setText('');
  };

  // React Compiler による自動メモ化の対象となる処理
  const expensiveCalculation = () => {
    console.log('Expensive calculation running...');

    let result = 0;
    for (let i = 0; i < 1000000; i++) {
      result += Math.sqrt(i);
    }
    return result;
  };

  const calculated = expensiveCalculation();

  return (
    <div className="w-full max-w-md rounded-lg border p-6 shadow-sm border-zinc-800 bg-zinc-950">
      <div className="space-y-4">
        <div>
          <h2 className="text-lg font-semibold text-zinc-50">
            React Compiler Verification
          </h2>
          <p className="mt-1 text-sm text-zinc-400">
            Component performance test with state updates
          </p>
        </div>

        <div className="space-y-3 rounded-md bg-zinc-800 p-4">
          <div>
            <p className="text-sm font-medium text-zinc-300">
              Count: <span className="font-bold text-blue-600">{count}</span>
            </p>
          </div>
          <div>
            <p className="text-sm font-medium text-zinc-300">
              Calculation Result:{' '}
              <span className="font-mono text-xs">{calculated.toFixed(2)}</span>
            </p>
          </div>
          <div>
            <p className="text-sm font-medium text-zinc-300 mb-2">
              Text Input:
            </p>
            <input
              type="text"
              value={text}
              onChange={(e) => setText(e.target.value)}
              placeholder="Type something..."
              className="w-full rounded border px-3 py-2 text-sm focus:border-blue-500 focus:outline-none border-zinc-600 bg-zinc-800 text-zinc-50 placeholder-zinc-500"
            />
          </div>
        </div>

        <div className="flex gap-2">
          <button
            onClick={handleIncrement}
            className="flex-1 rounded px-4 py-2 text-sm font-medium text-white active:bg-blue-800 transition-colors bg-blue-700 hover:bg-blue-600"
          >
            Increment
          </button>
          <button
            onClick={handleReset}
            className="flex-1 rounded px-4 py-2 text-sm font-medium active:bg-zinc-400 transition-colors bg-zinc-800 text-zinc-50 hover:bg-zinc-700"
          >
            Reset
          </button>
        </div>

        <div className="rounded p-3 text-xs bg-yellow-900/20 text-yellow-200">
          <p className="font-semibold">✓ React Compiler enabled</p>
          <p className="mt-1">
            This component is compiled by the React Compiler to optimize
            re-renders.
          </p>
        </div>
      </div>
    </div>
  );
};

Card コンポーネントでは以下を含む構成で動作確認を行います。

  • カウントの増加(Increment) 👈 ここはメモ化対象外❌
  • テキスト入力 👈 ここはメモ化対象⭕️
  • リセット実行 👈 ここはメモ化対象⭕️

React Compiler が最適化すると、重い計算(expensiveCalculation)が再実行されないことを確認できます。

3. 設定が有効か確認する

確認方法 1:ブラウザコンソール

expensiveCalculation() 内に console.log を仕込んでいるため、

状態更新後にログが再度出るかどうかで自動メモ化を確認できます。


確認方法 2:React DevTools

  1. React DevTools を開く
  2. 該当コンポーネントに“Memo ✨” バッジが表示される

さいごに

Next.js による React Compiler の導入はシンプルで、reactCompiler: trueを追加するだけで自動メモ化が有効になります。状態更新による無駄な再レンダーが抑えられ、特に重い計算や大規模 UI に効果があります。ただ、最適化されていない(できない)ケースもあるので、確認しながら修正していくことをお勧めします。

参照