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最適化 (TSKaigi2026 アフターパーティー)
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
seriseri
June 12, 2026
39
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
アンチパターンを避ける型駆動React最適化 (TSKaigi2026 アフターパーティー)
seriseri
June 12, 2026
More Decks by seriseri
See All by seriseri
アンチパターンを避ける型駆動React最適化
seriseri
0
7
AIに設計を書かせるだけで「理解負債」と「実装漏れ」が激減した話【フロントエンド編】
seriseri
1
140
「shadcn/ui × 自社デザインシステム」実践ガイド──FigmaトークンからTailwindまでの連携術
seriseri
0
17
フロントエンド開発にAIを“仕組みで”組み込む方法
seriseri
0
31
Featured
See All Featured
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.5k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
450
Music & Morning Musume
bryan
47
7.2k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
ラッコキーワード サービス紹介資料
rakko
1
3.7M
A Modern Web Designer's Workflow
chriscoyier
698
190k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
440
Automating Front-end Workflow
addyosmani
1370
210k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.9k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
Transcript
アンチパターンを避け 型駆動 React最適化 PeopleX / 芹澤和也
© PeopleX Inc. 3 アジェンダ 1. React Compilerとは 2. React
Compilerの仕組み 3. 最適化を阻害す アンチパターン 4. 対策
01 React Compilerとは © PeopleX Inc. 4
© PeopleX Inc. 5 React Compilerとは 5 // “とりあえず全部メモ化” 典型
const Row = memo((props) => { const label = useMemo(() => formatLabel(props.user), [props.user]); const onClick = useCallback(() => { props.onSelect(props.user.id); }, [props.user.id, props.onSelect]); return <li onClick={onClick}>{label}</li>; }); ⼿動メモ化のコスト • 依存配列の管理コスト • メモ化漏 、誤メモ化 • レビューコスト • バンドルサイズの肥⼤化
© PeopleX Inc. 6 React Compilerとは ⼿動メモ化 • useMemo •
useCallback • React.memo © PeopleX Inc. 6 こ まで React Compiler 爆誕 コンパイル時の⾃動メモ化 • useMemo • useCallback • React.memo こ から Before • 依存配列の正確さがチームに依存 • 再レンダリングが設計、レビューの中⼼ After • 誰でも • 設計中⼼は責務分離と副作⽤の隔離 React Compilerの登場
© PeopleX Inc. 7 React Compilerとは © PeopleX Inc. 7
とこ でReact Compilerって...
© PeopleX Inc. 8 React Compilerとは © PeopleX Inc. 8
どんなコンポーネントでも 最適化してく ??
© PeopleX Inc. 9 React Compilerとは © PeopleX Inc. 9
NO
© PeopleX Inc. 10 React Compilerとは © PeopleX Inc. 10
「純粋」なコンポーネントだけ 最適化(キャッシュ化)してく
© PeopleX Inc. 11 React Compilerとは © PeopleX Inc. 11
「純粋」= 同じ props を渡せ 必ず同じ結果を返し、レン ダー中に外部 状態を一切書き換えない(副作 用を持たない)コンポーネント こと
02 React Compilerの仕組み © PeopleX Inc. 12
© PeopleX Inc. 13 React Compilerの仕組み コンパイルのパイプライン(実⾏順序) 1. Parse(JSX /
TS → AST) — コードを構⽂⽊に分解す 2. 中間表現の構築 — 解析しやすい中間表現に整え 3. データフロー解析 — 値の依存関係を洗い出す 4. 副作⽤ / 可変性の推論 — 副作⽤がない範囲を⾒極め 5. メモ化境界の挿⼊ — 安全な範囲をキャッシュ化す © PeopleX Inc. 13
© PeopleX Inc. 14 React Compilerの仕組み © PeopleX Inc. 14
」 FunctionDeclaration UserList ├─ params: [ ObjectPattern { users, query } ] └─ body: BlockStatement ├─ VariableDeclarator filtered │ └─ CallExpression users.filter( ArrowFn ) ├─ VariableDeclarator count │ └─ MemberExpression filtered.length └─ ReturnStatement └─ JSXElement <List …/> function UserList({ users, query }) { const filtered = users.filter(u => u.name.includes(query)); const count = filtered.length; return <List items={filtered} total={count} />; } 1. Parse(JSX / TS → AST) — コードを構⽂⽊に分解す ⼊⼒コンポーネント 中間データ:AST(構⽂⽊)
© PeopleX Inc. 15 React Compilerの仕組み © PeopleX Inc. 15
2. 中間表現の構築 — 解析しやすい中間表現に整え 」 bb0 (entry): [1] $0 = LoadProp users.filter [2] $1 = FunctionExpr λ(u) [3] $2 = Call $0($1) ; → filtered [4] $3 = LoadProp $2.length ; → count [5] $4 = JSX <List items=$2 total=$3/> [6] Return $4 中間データ:HIR(SSA / basic blocks) function UserList({ users, query }) { const filtered = users.filter(u => u.name.includes(query)); const count = filtered.length; return <List items={filtered} total={count} />; } ⼊⼒コンポーネント
© PeopleX Inc. 16 React Compilerの仕組み © PeopleX Inc. 16
」 filtered := f(users, query) deps → { users, query } count := f(filtered) deps → { filtered } jsx := f(filtered,count) deps → { users, query } // 末端 JSX users / query に み依存 function UserList({ users, query }) { const filtered = users.filter(u => u.name.includes(query)); const count = filtered.length; return <List items={filtered} total={count} />; } 3. データフロー解析 — 値の依存関係を洗い出す ⼊⼒コンポーネント 中間データ:依存グラフ(reaching defs)
© PeopleX Inc. 17 React Compilerの仕組み © PeopleX Inc. 17
」 filtered := f(users, query) deps → { users, query } count := f(filtered) deps → { filtered } jsx := f(filtered,count) deps → { users, query } // 末端 JSX users / query に み依存 function UserList({ users, query }) { const filtered = users.filter(u => u.name.includes(query)); const count = filtered.length; return <List items={filtered} total={count} />; } 3. データフロー解析 — 値の依存関係を洗い出す ⼊⼒コンポーネント 中間データ:依存グラフ(reaching defs) 入力にしか依存していないことがわかる = 純粋
© PeopleX Inc. 18 React Compilerの仕組み © PeopleX Inc. 18
「純粋」= 同じ props を渡せ 必ず同じ結果を返し、レン ダー中に外部 状態を一切書き換えない(副作 用を持たない)コンポーネント こと
© PeopleX Inc. 19 React Compilerの仕組み © PeopleX Inc. 19
」 filtered := f(users, query) deps → { users, query } count := f(filtered) deps → { filtered } jsx := f(filtered,count) deps → { users, query } // 末端 JSX users / query に み依存 function UserList({ users, query }) { const filtered = users.filter(u => u.name.includes(query)); const count = filtered.length; return <List items={filtered} total={count} />; } 3. データフロー解析 — 値の依存関係を洗い出す ⼊⼒コンポーネント 中間データ:依存グラフ(reaching defs) 入力にしか依存していないことがわかる = 純粋
© PeopleX Inc. 20 」 React Compilerの仕組み © PeopleX Inc.
20 4. 副作⽤ / 可変性の推論 — 純粋性を満たす範囲を特定 5. メモ化境界の挿⼊ const $ = _c(5); // useMemoCache let filtered; if ($[0] !== users || $[1] !== query) { filtered = users.filter(u => u.name.includes(query)); $[0]=users; $[1]=query; $[2]=filtered; } else filtered = $[2]; const count = filtered.length; let t; if ($[3] !== filtered) { t = <List items={filtered} total={count}/>; $[3]=filtered; $[4]=t; } else t = $[4]; return t; 出⼒:メモ化済みコード
03 最適化を阻害す アンチパターン © PeopleX Inc. 21
© PeopleX Inc. 22 コンパイラに諦めら 3つのパターン © PeopleX Inc. 22
1. 副作⽤の混⼊ 2. ミュータブル操作 3. ⾮決定的な依存
© PeopleX Inc. 23 コンパイラに諦めら 3つのパターン © PeopleX Inc. 23
1. 副作⽤の混⼊ 2. ミュータブル操作 3. ⾮決定的な依存 」 function Total({ items }) { const total = items.reduce(...); logger.info(total); // I/O return <p>{total}</p>; }
© PeopleX Inc. 24 コンパイラに諦めら 3つのパターン © PeopleX Inc. 24
1. 副作⽤の混⼊ 2. ミュータブル操作 3. ⾮決定的な依存 」 function Profile({ user }) { user.name = user.name.trim() return <h1>{user.name}</h1>; }
© PeopleX Inc. 25 コンパイラに諦めら 3つのパターン © PeopleX Inc. 25
1. 副作⽤の混⼊ 2. ミュータブル操作 3. ⾮決定的な依存 」 function Token() { const id = Math.random(); return <p>{id}</p> }
04 対策 © PeopleX Inc. 26
© PeopleX Inc. 27 対策 © PeopleX Inc. 27 1.
型で防ぐ 2. Lintで防ぐ 3. 設計で防ぐ 4. ランタイムでの確認 // props を deep readonly で受ける type Props = { items: ReadonlyArray<Item>; user: Readonly<User>; }; function List({ items }: Props) { items.push(...) // ✕ コンパイルエラー const next = [...items, x]; // ◦ }
© PeopleX Inc. 28 コンパイラに諦めら 4つのパターン © PeopleX Inc. 28
1. 副作⽤の混⼊ 2. ミュータブル操作 3. 参照不安定性 4. ⾮決定的な依存 」 function Profile({ user }) { user.name = user.name.trim() return <h1>{user.name}</h1>; } こ を防ぐ!
© PeopleX Inc. 29 対策 © PeopleX Inc. 29 1.
型で防ぐ 2. Lintで防ぐ 3. 設計で防ぐ 4. ランタイムでの確認 // props を deep readonly で受ける type Props = { items: ReadonlyArray<Item>; user: Readonly<User>; }; function List({ items }: Props) { items.push(...) // ✕ コンパイルエラー const next = [...items, x]; // ◦ }
© PeopleX Inc. 30 対策 © PeopleX Inc. 30 1.
型で防ぐ 2. Lintで防ぐ 3. 設計で防ぐ 4. ランタイムでの確認
© PeopleX Inc. 31 対策 © PeopleX Inc. 31 Biome
Rust 製 高速 Lint / Formatter • noParameterAssign — 引数 再代入を禁止 • useReadonlyClassProperties — 不変表明を強制 • noUselessFragments / noUselessRename — render を清潔に保つ Oxc Rust 製 オールインワン JS/TS ツールチェイン • oxlint react-hooks/* — フック規約を高速検査 • react_compiler 互換ルール — 副作用混入を検出 Lintで防ぐ
© PeopleX Inc. 32 対策 © PeopleX Inc. 32 1.
型で防ぐ 2. Lintで防ぐ 3. 設計で防ぐ 4. ランタイムでの確認 純粋層 / 副作用層 / UI 層を物理的に分ける • 純粋層(Domain) ◦ 純粋関数 / 不変データ • 副作用層(Effects) ◦ I/O / fetch / storage / log ◦ 副作用 専用フック・サービスに隔離 • UI層 ◦ JSX / Server Components ◦ 純粋層 値をただ描画するだけ
© PeopleX Inc. 33 対策 © PeopleX Inc. 33 1.
型で防ぐ 2. Lintで防ぐ 3. 設計で防ぐ 4. ランタイムでの確認 純粋層 / 副作用層 / UI 層を物理的に分ける • 純粋層(Domain) ◦ 純粋関数 / 不変データ ◦ Compiler が最適化できる純粋層 • 副作用層(Effects) ◦ I/O / fetch / storage / log ◦ 副作用 専用フック・サービスに隔離 • UI層 ◦ JSX / Server Components ◦ 純粋層 値をただ描画するだけ コンテナ・プレゼンターパターン (+hooks)
© PeopleX Inc. 34 対策 © PeopleX Inc. 34 1.
型で防ぐ 2. Lintで防ぐ 3. 設計で防ぐ 4. ランタイムでの確認
35