React Compiler を導入したら、useMemo だらけのコードから解放された話

React Compiler を実際に仕事のプロジェクトに導入してみたら、手動で書いていた useMemo・useCallback の大半が不要になりました。導入手順とハマった点をまとめています。

🙌 結論から

React Compiler を仕事のプロジェクトに導入してみました!

結論から言うと、手動で書いていた useMemouseCallback の大半が不要になり、コードの見通しがかなり良くなりました。

最初は「本当にビルド時の最適化だけでパフォーマンスが保てるのか」と半信半疑だったんですが、実際に触ってみると杞憂でした(^_^)

もちろん全部のケースで完璧というわけではなく、いくつか注意点もあったので、そのあたりも正直に書いておきます。

💡 React Compiler とはなにか

React Compiler は、コンポーネントの再レンダリングを自動で最適化してくれるビルド時コンパイラです。

これまで開発者が手動で useMemouseCallbackReact.memo を書いて防いでいた不要な再レンダリングを、コンパイラが静的解析して自動的にメモ化してくれます。

つまり、メモ化のためのボイラープレートを書かなくてよくなるというのが最大のポイントです!

Babel プラグインとして動作するので、Vite でも Next.js でも比較的組み込みやすいのも助かるポイントでした🙌

👀 導入してみた

導入はプラグインの追加とインストールだけで済みます。

npm install babel-plugin-react-compiler eslint-plugin-react-compiler

Vite の場合は vite.config.ts の Babel プラグインとして追加するだけです。

react({
  babel: {
    plugins: [['babel-plugin-react-compiler', {}]],
  },
})

ESLint プラグインも一緒に入れておくと、コンパイラのルール違反(副作用のある処理をレンダー中に書いているなど)を事前に検出してくれます。

私のプロジェクトでは導入直後に十数件のルール違反が検出されました(・_・;)

ほとんどは「レンダー関数の中で配列を直接書き換えていた」ような、そもそも良くない書き方だったので、直しがてらコードの品質も上がった感覚があります。

✨ 実際に消えたコード

一番わかりやすかったのは、フィルタリング処理を含む一覧画面のコンポーネントです。

// 導入前
const filteredItems = useMemo(
  () => items.filter((item) => item.category === category),
  [items, category]
);
const handleSelect = useCallback(
  (id: string) => setSelectedId(id),
  []
);

これが導入後は、こう書くだけで済むようになりました。

// 導入後
const filteredItems = items.filter((item) => item.category === category);
const handleSelect = (id: string) => setSelectedId(id);

同じコンポーネント内で useMemo が7〜8個並んでいた画面もあったんですが、そのほとんどを削除できました!

React DevTools の Profiler で確認しても、再レンダリングの回数は導入前とほぼ変わらず、むしろコードだけがスッキリした印象です(´・∀・)

さりげない差分に見えて、レビュー時に「このメモ化は本当に必要か」を毎回悩まなくてよくなったのは、思っていたより大きいメリットでした。

👍 使ってみた感想

一番よかったのは、新しくコンポーネントを書くときに悩む選択肢が減ったことです。

「ここは useCallback で包むべきか」を考える時間がまるごと消えたので、実装のスピードが上がった実感があります!

一方で、サードパーティのライブラリと組み合わせている一部のフックでは、コンパイラのルールに引っかかって自動メモ化が効かないケースもありました。

そういう箇所は "use no memo" ディレクティブで個別に除外できるんですが、最初は原因の切り分けに少し時間がかかりました(´・ω・`)

とはいえ全体で見ると、既存コードの99%は無修正か軽微な修正だけで移行できたので、導入コストは想像していたよりだいぶ低かったです。

パパ系Webエンジニア〜愛用ガジェット一覧 🛍️

この記事を書いている作業環境のガジェットを楽天ROOMにまとめています ✨ 在宅エンジニアのデスク作りの参考にどうぞ 🙌

🙌 まとめ

React Compiler は、手動メモ化のボイラープレートをビルド時の自動最適化に置き換えてくれるツールです。

useMemouseCallback を書くたびに依存配列で消耗していた人ほど、恩恵を感じやすいと思います!

まずは ESLint プラグインだけ先に入れて、既存コードの警告を確認するところから始めるのがおすすめです🙌

次に新規コンポーネントから徐々に慣らしていけば、無理なく移行できるはずです(^o^)/