🎉

React Compiler v1.0がリリースされました!

に公開4

TERASSエンジニアの@shuji_koikeです!

昨年弊社のテックブログで同僚の@myrear"React Forget は何を「忘れ」させてくれるのか"という秀逸なタイトルの記事を投稿したところトレンド入りを果たし、弊ブログとしては快挙と言える数の「いいね」をいただきました。

そしてついに先日React Conf 2025に合わせて、React Forgetは名前を変えてReact Compiler v1.0 babel-plugin-react-compiler@1.0.0としてリリースされました!

React CompilerのRC版は一年近く前から公開されているので、すでに導入しているプロジェクトも多いかもしれません。
弊社ではRC版を導入・検証しているプロダクトはまだなかったので、今回はじめてReact Compilerの導入を検証してみて感じたことをこの記事でお伝えします。

結論

まずは単刀直入に結論からお伝えします!

  • 手動で簡単にmemo化できる部分はそこそこ自動で最適化される
  • 手動でmemo化するのが難しい・間違いやすいケースではほとんど最適化が効かない印象
    • 残念ながらmemo化を全く意識しなくていい世界にはならないが大きな前進だとは思う
  • チューニングの手段はmemo化だけではないので、色々な手法を効果的に使えば手動のmemo化はかなり減らせそう
  • 特に新規のプロジェクトには迷いなく導入した方がよさそう🙌
  • 既存のMVPプロダクトに追加で導入してみた感触としてはおおむね良好👍
  • 既存の大きめのプロダクトに導入する場合はリスクが大きいので、インクリメンタルに導入する仕組みを使うのが良さそう⚠️
  • React Compilerを導入しないとしても、React Compilerの成果によって強化されたeslint-plugin-react-hooksexhaustive-depsなどのルールを厳守することが導入に向けた第一歩となる

MVPフェーズの小規模なプロダクトに導入してみた感触

直近自分が開発を担当しているAIを組み込んだ診断ツールに導入してみました。
ざっくりとreact@19 + vite@7 + firebase + openaiのような構成です。
状態管理には@tanstack/react-queryzustandを入れています。
まだ(MVP)のフェーズなので結構雑な作りになってしまっていて、最適化前だとinputで文字を打つたびに画面全体が再レンダリングされる状態です。
また、openaiの出力をcloud functionからストリームで受け取っていて、数文字のstringを受け取るたびに再レンダリングが発生する画面があります。
既存のコードは体感できるレベルの問題は発生していないため、memo化のチューニングは全く施していませんでした。
React Compilerの検証にはうってつけのコードベースですね!

導入

ドキュメントに従ってvite.config.ts"babel-plugin-react-compiler"を追加しただけですんなりと導入できました!
単に導入しただけでpropsのないコンポーネントなどは再レンダリングが抑制されるようになりました。ただし状態管理が複雑なコンポーネントでは自動最適化がかからないところがありました。実害はないけれども最適化されていたらベターだなって部分です。原因と思われる部分を手動でuseCallbackしてみたりContextを使ってみたりしたのですがうまくいかず、React.memoを含めてほぼ従来通り手動でチューニングする必要がありました。この辺りReact Compilerの挙動がまだまだ掴めていません。
最終的には一部の状態管理をzustandで管理するようにしたところ、全くmemo化せずに自動最適化が効くようになりました!
これによってコードベース全体でReact.memo,useMemo,useCallbackを一切使っていないにもかかわらず必要十分に再レンダリングが抑制できている状態になりました。素晴らしいことです!すばら!

効果

フォームが主体のプロダクトですが、フォームを5つのステップ(別route)に分割しているので、レンダリングの重さは元から体感できない状態でした。
なのでComliler導入の効果は体感としてはほとんど感じられないものの、Dev toolsで再レンダリングをハイライトさせて見てみると、memo化では抑制できない部分を除けばほとんど再レンダリングが抑制できていて、心理的な安心感が得られる効果は超絶絶大だと思いました。

react@18のviteプロジェクトに導入してみる

次に弊社の立ち上げ初期から開発・運用している、まだreact@18のプロダクト(Terass Offer)のコードベースに導入を試みました。このプロダクトはチャットを主体としたサービスです。
過去に、ヘビーユーザーのチャットルーム一覧やプロフィールの編集フォームの入力時にパフォーマンスが問題になり、memo化のチューニングを施してあります。フォームのチューニングは私がTERASSに入社して最初に渡されたタスクでした!
それ以外の部分はuseMemo,useCallbackを不用意に使わないというルールを徹底して実装されています。体感でレンダリングが重いと感じることはあまりないものの、Dev toolsで再レンダリングを視覚化するとかなりわちゃわちゃしてます😅

導入

react-compilerreact@18にも対応していますが、react-compiler-runtimeが追加で必要になります。さらにbabel.config.js設定を追加する必要があるようです。ドキュメントはあまり詳しく設定方法が書かれていなくて、カンで設定してみたものの下記のエラーが出てしまいました。

error when starting dev server:
Error: Missing "./compiler-runtime" specifier in "react" package

こちらの記事に詳しく設定がまとめられていて、こちらを参考にしたら解決できました!

効果

体感としては違いは正直感じられません。元々重い部分はmemo化が効いているからでしょうか。Dev toolsで再レンダリングを視覚化してみた感じもほとんんど変わらずちょっと期待はずれ。プロファイルを取ればなんらか定量的な差が出るだろうと思ったものの誤差の範囲。react@18のプロジェクトでは本来の効果が得られないということかもしれません。幸い悪影響が出ていると言うことはなさそうです。
明示的にmemoしている部分を解除してみたところ、自動でmemo化してくれましたが、そのコンポーネントに渡している関数のuseCallbackを外すと再レンダリングが抑制できなくなってしまいました。多段でprops drillingしているのが原因かもしれません。

まとめ

以上、まだ1週間ほどですがReact Compilerを触ってみた感想でした。
やはりReact Compilerを導入するメリットは、導入によるパフォーマンスの向上そのものよりも、memo化を忘れさせてくれることにあると思いました。

今回の記事はタイムリーな話題として投稿したかったのでコード例や計測値などをまとめる余裕がなく、感覚的な内容ばかりになってしまいました。
今後Terass OfferにReact Compilerを本格導入する際には、その過程や得られた知見を共有できればと思います。
Likeボタンを押して応援お願いします💕

Terass Tech Blog

Discussion

Shuji KoikeShuji Koike

npm create vite@latestで「TypeScript + React Compiler」を選択できるようになっているが、現時点ではRC版がインストールされてしまう?😅

"babel-plugin-react-compiler": "^19.1.0-rc.3",