ADR-0047: React Compiler を、apps/playground にだけ入れる¶
Status¶
承認
Context¶
React Compiler を入れるかと、入れる範囲を決める必要がある。
- プレイグラウンドのアプリは、Vite の React のアプリである。
- プレイグラウンドの画面は、エディタ、端末、HTTP の一覧のように、更新の多いペインを持つ。
- React Compiler は、コンポーネントと hook を、ビルドのときに自動でメモ化する。react.dev は、stable と書いている。
- Vite では、
@vitejs/plugin-reactと@rolldown/plugin-babelのreactCompilerPresetで入れる。 apps/webは Astro のアプリで、React の island は少ない。@astrojs/reactのcompilerのオプションは、試験的である。packages/uiは、memo、useMemo、useCallbackを使っていない。- ツールを追加するときは、同梱のツールで足りるものを別に入れず、beta のツールを採るときは、撤退の手段を書く。
Decision¶
React Compiler を、apps/playground のビルドにだけ入れる。
apps/web のビルドと、packages/ui の Storybook とテストには入れない。
apps/playgroundのvite.config.tsに、@rolldown/plugin-babelとreactCompilerPresetを追加する。apps/playgroundのコードには、memo、useMemo、useCallbackを書かない。書くのは、計測して遅いと分かったときだけにする。apps/playgroundのビルドは、import した@fukuemon/uiのソースも、React Compiler に通す。@fukuemon/uiのコードは、React Compiler が無くても動く形で書く。- React Compiler を外すときは、
vite.config.tsから plugin を外す。コードは変えない。
理由は、更新の多いペインで、手でメモ化を書かずに済むことである。
Verification¶
使い捨てのアプリ(ADR-0046 の Verification と同じもの)に、@rolldown/plugin-babel 0.3.1 と babel-plugin-react-compiler 1.0.0 を追加してビルドした。
- ビルドが通った。エントリーポイントのチャンクに、React Compiler が出力するキャッシュのコード(
memo_cache_sentinel)が入った。React Compiler を外すと、入らなかった。 - 共有のチャンクは、React Compiler を外すと 213.76 kB、入れると 222.55 kB だった。
@fukuemon/uiのソースが、React Compiler を通っている。 - ビルドの時間は、外すと 0.52 秒、入れると 1.11 秒だった。
- 再描画の回数と、画面の動きは、測っていない。
Considered Options¶
| 選択肢 | 強み | 弱み |
|---|---|---|
採用: apps/playground にだけ入れる |
更新の多い画面で、手で memo、useMemo、useCallback を書かずに済む |
Babel の plugin が増える。ビルドの時間が増える |
| 入れない | 依存が増えない | 再描画が遅いときに、手でメモ化を書く |
apps/web と packages/ui にも入れる |
全ての React のコードで、同じ前提になる | apps/web の island は少なく、効果が小さい。@astrojs/react の compiler は、試験的である |
Consequences¶
Positive¶
apps/playgroundのコードに、メモ化のための hook を書かない。- React Compiler を外すときに、コードを変えずに済む。
Negative¶
apps/playgroundのビルドに、Babel の変換が加わる。@fukuemon/uiのコンポーネントは、カタログ(React Compiler なし)と、プレイグラウンド(React Compiler あり)の 2 つの形でビルドされる。再描画の回数が、2 つで違う。- React の規則(描画の中で値を書き換えない、など)に反するコードは、React Compiler がメモ化を外す。規則に反するコードを lint で止めるかは、決めていない。