Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
React Compiler導入から21ヶ月、いま始めるならこうやる
Search
Tatsuya Asami
May 16, 2026
Technology
360
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
React Compiler導入から21ヶ月、いま始めるならこうやる
Tatsuya Asami
May 16, 2026
More Decks by Tatsuya Asami
See All by Tatsuya Asami
NestJSのコードからOpenAPIを自動生成する際の最適解を探す
astatsuya
0
610
終わってる風終わってないタスクが自分の首を締めた話
astatsuya
0
520
Other Decks in Technology
See All in Technology
プライバシー保護の理論と実践
lycorptech_jp
PRO
1
240
トークン最適化のためのユーザーストーリー分析 / User Story Analysis for Token Optimization
oomatomo
0
170
Hatena Engineer Seminar 37 jj1uzh
jj1uzh
0
430
Kotlin 開発のツラミを爆破した話! / Explode the difficulty of Kotlin dev!
eller86
0
140
#エンジニアBooks 30分でわかる 「技術記事を書く技術」 / engineer-books 2026-06-30
jnchito
1
190
デジタル・デザイン構想 by Sayaka Ishizuka
y150saya
0
190
インフラ寄りSREでも 開発に踏み出せる〜境界を越えてユーザー体験に向き合いたい〜
sansantech
PRO
0
480
組織における AI-DLC 実践
askul
0
310
攻撃者がいなくてもAIエージェントはインシデントを起こす
nomizone
0
200
スタートアップにおけるアジャイルの実践について #shibuyagile
murabayashi
3
2.1k
アラート調査向けAIエージェントの本番導入とその後/AI Agents for Alert Investigation: Production Deployment and After
taddy_919
1
380
型は壁、Rustでもバグを直すな、表現できなくせよ
nwiizo
10
1.1k
Featured
See All Featured
Designing Powerful Visuals for Engaging Learning
tmiket
1
440
The #1 spot is gone: here's how to win anyway
tamaranovitovic
3
1.1k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
240
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
170
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
460
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.1k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
440
Fireside Chat
paigeccino
42
4k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
Google's AI Overviews - The New Search
badams
0
1.1k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
200
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
800
Transcript
React Compiler導⼊から21ヶ⽉、 いま始めるならこうやる 2026年5月20日 useMemo/useCallbackまだ書いてる?React Compilerで変わった開発体験 浅見 達也@astatsuya1
自己紹介 浅⾒ 達也 (@astatsuya1) • 2024年7⽉頃にexperimental版だったReact Compilerを有効にしました ◦ ZennでReact Compilerを有効にして9ヶ⽉が経ちましたを書きました
▪ https://zenn.dev/dev_commune/articles/e42847c9ce3c97 ▪ 正式版リリース前の話なので参考程度にして下さい • コミューン株式会社 プラットフォームエンジニアリング本部 本部⻑ ◦ ⾊々やるが私はフロントエンドが得意
© Commune Inc. All rights reserved ⽬次 1. React Compilerとは?
2. 導⼊時におきたこと 3. 導⼊後の変化 4. これから導⼊するなら 5. まとめ
© Commune Inc. All rights reserved React Compilerとは? 4
React Compilerとは? • React アプリを⾃動的に最適化する新しいビルド時ツールです。 ◦ https://ja.react.dev/learn/react-compiler/introduction • React Compilerを使わない場合はuseCallback、useMemo,
React.memo等 を使って⼿動でメモ化する必要がある • React Compilerを使うと⾃動でメモ化してくれる • babel-plugin-react-compiler v1.0.0が2025年10⽉にリリースされた ◦ 2026年5⽉14⽇現在もv1.0.0が最新版
React Compilerとは? // React Compilerを使用しない場合 import { useMemo, useCallback, memo
} from 'react'; const ExpensiveComponent = memo(function ExpensiveComponent({ data, onClick }) { const processedData = useMemo(() => expensiveProcessing(data), [data]); const handleClick = useCallback((item) => onClick(item.id), [onClick]); return ( <div> {processedData.map((item) => ( // onClickに渡しているアロー関数はレンダーごとに新しく作られるため、handleClickをメモ化してもItemのメモ化は効かない <Item key={item.id} onClick={() => handleClick(item)} /> ))} </div> ); }); 出典:https://ja.react.dev/learn/react-compiler/introduction#before-react-compiler
React Compilerとは? // React Compilerを使用する場合 function ExpensiveComponent({ data, onClick })
{ // React.memoは不要 const processedData = expensiveProcessing(data); // useMemoは不要 const handleClick = (item) => onClick(item.id); // useCallbackは不要 return ( <div> {processedData.map((item) => ( // onClickに渡しているアロー関数はitemが変わらない限り同じ関数が使い回されるため、Itemのメモ化が効く <Item key={item.id} onClick={() => handleClick(item)} /> ))} </div> ); } 出典:https://ja.react.dev/learn/react-compiler/introduction#after-react-compiler
© Commune Inc. All rights reserved 導⼊時におきたこと 8
導入時におきたこと なぜReact Compilerがexperimental版の段階で導⼊したのか? • データ周りの⼤きなアップデートがあり全機能テストをしないといけな かった • どうせ全機能をテストするなら後々変更するのが怖いことをやっておきた かった ◦
react19, next15へのアップデートと、react-compilerの導⼊をやった ◦ いずれもソースコードの変更量は少なく、リリース前に問題があった らダウングレードや無効化で撤退できそうだった
導入時におきたこと どうやって進めたか • ソースコードはディレクトリごと複製 • 新旧それぞれのコードをデプロイ • 顧客が使っている環境とは隔離することで影響が出ないようにして進めた ◦ 違和感を感じた時に元々そうだったのか挙動が変わってしまったのか
確かめやすかった ◦ 気軽にマージ出来て少しずつ検証ができた
導入時におきたこと どんな感じだったか • ⼤体は期待通りメモ化されそのまま動いた! • ⼀部動かない箇所は頑張って書き換え、時間がかかりそうな箇所はuse no memoディレクティブ をつけた ◦
1ページだけ。5コンポーネントくらいにつけた • 全てのuseCallbackやuseMemo等を外したわけではない ◦ useCallbackを外すとuseEffectが無限ループする箇所があった ◦ 撤退も選択肢に残しておきたかったので、触る必要のないコードはそのままにしていた • そんなことがありながら無事React Compilerを有効にした状態でリリース
© Commune Inc. All rights reserved 導⼊後の変化 12
導入後の変化 • とても良かった ◦ メモ化のことを気にせず開発できるようになったこと ▪ 考えることが減ってその分他のことに集中できるようになった ◦ 記述量が減ってコードが読みやすくなった •
そうでもなかった ◦ ユーザー⽬線で嬉しいことはなさそうだった ▪ 確かに多くのコンポーネントはメモ化されてパフォーマンスは上がって いた ▪ おそらくどれも数10msの差で、⾔われなければ気が付かない程度
© Commune Inc. All rights reserved 今からやる場合の導⼊⼿順 14
今からやる場合の導入手順 移⾏⼿順 1. eslint-plugin-react-hooksを⼊れて違反を直す 2. React Hook Formの使い⽅を⾒直す 3. React
Compilerが有効な状態で⾃動テストを実⾏する 4. 段階的に有効にする
今からやる場合の導入手順 1. eslint-plugin-react-hooksを⼊れて違反を直す • React公式が提供しているリンター • hooksだけでなくReact全般のルール • 元々React Compilerのリンターはeslint-plugin-react-compilerだったが、
React Compilerの安定版が公開されたタイミングで統合された ◦ https://react.dev/blog/2025/10/07/react-compiler-1#migrating-from-eslint-plugin-reac t-compiler-to-eslint-plugin-react-hooks
今からやる場合の導入手順 1. eslint-plugin-react-hooksを⼊れて違反を直す • eslint-plugin-react-hooksはbabel-plugin-react-compilerと同じチェック ロジックを使っている ◦ リントで多くの違反を事前に検出出来る(※ただし全てではない) • React
Compiler は最適化すると壊れそうなコードを⾒つけた場合に、最適 化をスキップしてくれる事がある ◦ スキップ対象は重⼤度がError相当の場合のみ。Warning以下はスキッ プされない(最適化されると壊れる可能性がある)
今からやる場合の導入手順 1. eslint-plugin-react-hooksを⼊れて違反を直す • つまり違反だらけの状態で有効にしても最適化の効果は薄いし、動かなくなる可 能性もある • oxlintでもjsPluginsを使えばチェックできる ◦ https://oxc.rs/docs/guide/usage/linter/plugins.html#supported-plugins
ここの下の⽅にあるリ ンク先のissueに設定⽅法が書いてある • biome等別のリンターを使っていて、リンターの併⽤をしたくない場合でも、⼀ 度違反がないか検出してみるのをおすすめ → まずはeslint-plugin-react-hooksで違反がない状態を⽬指しましょう
今からやる場合の導入手順 2. React Hook Formの使い⽅を⾒直す • React Compiler関係なく従う必要のあるルールがある。例えば、 ◦ formStateはレンダリングフェーズでプロパティへのアクセスを発⽣させる
必要がある ▪ https://react-hook-form.com/docs/useform/formstate ◦ リアクティブに値を更新したい箇所ではuseWatchを使い、⼀度だけ使いた い時はgetValuesを使う ※ 詳しい説明は省略させていただきます。React Hook Formの内部実装に依存しているので今後変わる可能性 もあります。
今からやる場合の導入手順 2. React Hook Formの使い⽅を⾒直す • 前ページのようなReact Hook Formのルールに加えて、React Compilerと
併⽤する場合は下記のルールも追加する ◦ watchは使わずuseWatchを使う ◦ formStateは使わずuseFormStateを使う ◦ resetとuseFormの引数のvaluesはregisterを使っていると動かないの で、controllerを使う ※私の経験上はこれで⼤丈夫ですが、他に動かないパターンもあるかもしれません
今からやる場合の導入手順 2. React Hook Formの使い⽅を⾒直す • React Hook FormとReact Compilerの挙動をテストしている⼈がいたの
で、 そのコードを利⽤させてもらい2026年5⽉時点の最新バージョンに上 げて試してみたところ、前ページのルールに従っているテストは全て通り ました ◦ https://github.com/timkindberg/rhf-compiler-compat (PRマージしてもらった) ◦ 以前は半分くらいのテストが落ちていた
今からやる場合の導入手順 2. React Hook Formの使い⽅を⾒直す • React Hook Form +
React Compilerのリンターを使う ◦ eslint-plugin-react-hooksのincompatible-libraryでuseFormの戻り値の watchはWarningを出してくれる ▪ ただし、useFormContextの戻り値のwatchはチェックしてくれない ◦ eslint-plugin-react-hook-formというのもある ▪ formStateやuseFormContextの戻り値のwatchもチェックしてくれる
今からやる場合の導入手順 3. React Compilerが有効な状態で⾃動テストを実⾏する • babel/jestはpluginsにbabel-plugin-react-compilerを追加すればOK • bun testはtransform処理を噛まして動いていた ◦
https://github.com/timkindberg/rhf-compiler-compat/blob/main/compiler-plugin.ts • 私の環境のnext/jestはjestの複雑なtransform処理の追加が必要でした ◦ ⾊々な要素が絡んで難しかった ◦ AIが作ってくれたが正直何をやっているのかわからない
今からやる場合の導入手順 // jest.config.compiler.js const nextJest = require('next/jest' ) const swc
= require('@swc/core' ) const babel = require('@babel/core' ) // === Transformer: SWC → Babel の 2 段構成 === const reactCompilerTransformer = { process(src, filename) { // ① SWC: TS strip するが JSX は残す(runtime: 'preserve' ) const swcResult = swc.transformSync (src, { filename, jsc: { parser : { syntax: 'typescript' , tsx: true }, transform : { react: { runtime : 'preserve' } } }, module : { type: 'es6' } }) // ② Babel: JSX 変換 + React Compiler + CJS 化 const babelResult = babel.transformSync (swcResult.code, { filename, presets : [['next/babel' , { 'preset-react' : { runtime : 'automatic' } }]], plugins : [['babel-plugin-react-compiler' , { target : '19' }]] }) return { code: babelResult .code } } } // === Jest 設定: next/jest の transform を差し替える === const createJestConfig = nextJest({ dir: __dirname }) module.exports = async () => { const base = await createJestConfig ({})() return { ...base, transform : { ...base.transform, '^.+\\.(js|jsx|ts|tsx|mjs)$' : reactCompilerTransformer } } } こんなイメージ。実際はもっと⾊々やっていて132⾏になった。
今からやる場合の導入手順 4. 段階的に有効にする • 部分的に無効、部分的に有効どちらも出来る ◦ compilationMode: infer + “use
no memo”ディレクティブで部分的に無効にする ◦ compilationMode: annotation + “use memo”ディレクティブで部分的に有効にす る • ディレクティブ以外でもゲーティングを使って制御出来る ◦ https://ja.react.dev/learn/react-compiler/incremental-adoption#runtime-feature-flags-with-gating ◦ Next.jsの場合だとこのオプションは使えない様⼦
今からやる場合の導入手順 ◦ ローカルでReact Compilerを動かすのは設定を ちょっと変えるだけ。どれくらい⼤変そうかもリン ターを実⾏してみればわかるので気軽にやってみま しょう
© Commune Inc. All rights reserved まとめ 27
まとめ • React Compilerを有効にすることで、メモ化する、しないを頭から切り離 す事が出来て⾮常に良かった • 今ならReact Hook Formも⼀定のルールに従えばReact Compilerと共存出
来る可能性が⾼い • eslint-plugin-react-hooksはReactの教科書 ◦ React Compilerを有効にするつもりがない⼈もルールを読んでみると ためになる
© Commune Inc. All rights reserved ご静聴いただきありがとうございました! 29