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
65
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
13
AIに設計を書かせるだけで「理解負債」と「実装漏れ」が激減した話【フロントエンド編】
seriseri
1
150
「shadcn/ui × 自社デザインシステム」実践ガイド──FigmaトークンからTailwindまでの連携術
seriseri
0
19
フロントエンド開発にAIを“仕組みで”組み込む方法
seriseri
0
32
Featured
See All Featured
Site-Speed That Sticks
csswizardry
13
1.4k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.3k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
410
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
56k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
700
Technical Leadership for Architectural Decision Making
baasie
3
470
Darren the Foodie - Storyboard
khoart
PRO
3
3.6k
The SEO Collaboration Effect
kristinabergwall1
1
520
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.5k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
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