Slide 1

Slide 1 text

Reactを段階的に覗いてみる 安井大晟(ytaisei_)

Slide 2

Slide 2 text

自己紹介 ● 株式会社AI Shift ○ Webフロントエンド ○ LLMを活用した新規事業 ● 社会人1年目 ● AI Agentの開発をしています

Slide 3

Slide 3 text

第一回React TokyoのLTでも登壇させていただきました!

Slide 4

Slide 4 text

普段意識しているReact ● 状態管理 ● コンポーネント設計 ● データフェッチ戦略 など

Slide 5

Slide 5 text

普段意識しているReact ● 状態管理 ● コンポーネント設計 ● データフェッチ戦略 など Reactのコンポーネントが どのようにブラウザにレンダリングしているかを意識する必要はない

Slide 6

Slide 6 text

Reactを覗いていきましょう

Slide 7

Slide 7 text

段階を追って理解する 1. React Componentが宣言的にレンダリング される 2. JSXがトランスパイル されReact Elementに変換される 3. React Nodeを元にFiber Treeが構築され DOMを操作し、ブラウザにレンダリングされる *段階を追って理解をするため、あえて抽象的な表現を使っています

Slide 8

Slide 8 text

段階を追って理解する 本日のゴールは Reactのソースコードから 実際にDOMの操作をしている箇所に辿り着くことです!

Slide 9

Slide 9 text

1. React Componentが宣言的にレンダリングされる

Slide 10

Slide 10 text

React Componentが宣言的にレンダリングされる ● JSX構文でDOM構造とスタイリングをする ● Stateを用いてリアクティブな画面を設計する ● useEffectで副作用を管理する など

Slide 11

Slide 11 text

React Componentが宣言的にレンダリングされる ● JSX構文でDOM構造とスタイリングをする ● Stateを用いてリアクティブな画面を設計する ● useEffectで副作用を管理する など 命令的に DOMの操作をする必要がないのは 宣言的UIのメリット

Slide 12

Slide 12 text

ところで、 JQueryだったりで命令的に Webフロントを開発する 機会は減ったのではないでしょうか

Slide 13

Slide 13 text

当時の自分の感覚 JSXが直接描画されてる???

Slide 14

Slide 14 text

実際は複数のフェーズに分かれている

Slide 15

Slide 15 text

実際は複数のフェーズに分かれている 今回はブラウザのレンダリング処理までは話せません ...

Slide 16

Slide 16 text

2. JSXがトランスパイルされ React Elementに変換される

Slide 17

Slide 17 text

JSXがトランスパイルされReact Elementに変換される

Slide 18

Slide 18 text

JSXがトランスパイルされReact Elementに変換される JSXはJSの構文拡張なのでそのまま実行ができない ビルド時に babelなどでのトランスパイル処理が必要

Slide 19

Slide 19 text

JSXがトランスパイルされReact Elementに変換される 参考:https://babeljs.io/docs/babel-plugin-transform-react-jsx Classic React17以降

Slide 20

Slide 20 text

JSXがトランスパイルされReact Elementに変換される React Elementの型定義 React Elementの例

Slide 21

Slide 21 text

JSXがトランスパイルされReact Elementに変換される React Element React Node

Slide 22

Slide 22 text

JSXがトランスパイルされReact Elementに変換される React Element React Node ReactNodeはReactElementを内包する Reactがレンダーできるすべての値を表す型

Slide 23

Slide 23 text

次に発生する疑問 オブジェクトってレンダリングできる???

Slide 24

Slide 24 text

3. React Nodeを元にFiber Treeが構築され DOMを操作し、ブラウザにレンダリングされる

Slide 25

Slide 25 text

Reactの基本 - createRoot 1. getElementByIdでtargetのDOMを取得 2. targetのDOMをcreateRootに渡す 3. root.renderにレンダリングしたい React Nodeを渡す root.renderにレンダリング対象の React Nodeを渡す

Slide 26

Slide 26 text

root.renderの中では何をしてる ...?

Slide 27

Slide 27 text

ReactElementを元にFiberTreeが構築されDOMを操作し、ブラウザにレンダリングされる

Slide 28

Slide 28 text

React Fiberについて

Slide 29

Slide 29 text

React Fiber Architectureについて https://jser.dev/2023-07-14-initial-mount/#1-brief-introduction-on-fiber-architecture https://github.com/acdlite/react-fiber-architecture?tab=readme-ov-file 「React Fiber Architecture」 Reactは内部でFiber Treeを構築して 差分の更新を最小限に抑えている

Slide 30

Slide 30 text

React Fiber Architectureについて - Reconciliation ● currentはUIに描画される 現在のバージョンのFiberTree / Node ● workInProgressは 新たに構築しているFiberTree / Node これらを比較して差分を検知する

Slide 31

Slide 31 text

React Fiber Architectureについて - 4つの実行フェーズ 1. Trigger Phase 2. Schedule Phase a. 実行されるタスクに優先順位を設定 する b. Fiber Architectureの中でも特に重要(今回はスキップ) 3. Render Phase a. スケジュールされたタスクを実行し、 新しいFiber Treeを構築してDOMに変更が必要な対象を整理 4. Commit Phase a. 更新対象をDOMに反映

Slide 32

Slide 32 text

Render Phase

Slide 33

Slide 33 text

Performタブで確認する(初回マウントの場合)

Slide 34

Slide 34 text

Render Phase - renderRootSync RootのFiberNodeから順に FiberTreeを構築する 対象のコード:renderRootSync 1. prepareFreshStackでFiberTree構築 のための準備をする 2. workLoopSyncでworkInProgressがnullになる(末 端のFiberNodeに到達する)まで performUnitOfWorkを実行する

Slide 35

Slide 35 text

Render Phase - performUnitOfWork 各FiberNodeごとにbeginWorkを実行する

Slide 36

Slide 36 text

Render Phase - performUnitOfWork FiberNodeごとにbeginWorkを実行する 対象のコード:beginWork

Slide 37

Slide 37 text

Render Phase - completeWork 対象のコード:completeWork 1. createInstanceで実際の DOMのインスタンスを作成 2. appendAllChildrenでサブツリーのDOM Nodeを全 てappendしたDOM Nodeを作成 3. それをstateNodeに代入 completeWorkをFiber Treeを逆に戻るように実行

Slide 38

Slide 38 text

Render Phase - completeWork 対象のコード:completeWork 1. createInstanceで実際のDOMの インスタンスを作成 2. appendAllChildrenでサブツリーのDOM Nodeを全 てappendしたDOM Nodeを作成 3. それをstateNodeに代入 completeWorkをFiber Treeを逆に戻るように実行

Slide 39

Slide 39 text

Render Phase - 全体像 Fiber Treeが完成し必要な DOM Nodeが作成され、 DOM操作が必要な FiberNodeに フラグをつけることができた

Slide 40

Slide 40 text

Commit Phase

Slide 41

Slide 41 text

実際は複数のフェーズに分かれている

Slide 42

Slide 42 text

Commit Phase 1. 再帰的に削除予定の子要素を削除する 2. 実際にDOMの挿入を行う (この実装を見ていきましょう) Fiber Treeを元にDOMの削除と更新を行う 対象のコード:commitMutationEffects

Slide 43

Slide 43 text

段階を追って理解する 本日のゴールは Reactのソースコードから 実際にDOMの操作をしている箇所に辿り着くことです! https://github.com/facebook/react/blob/4f604941569d2e8947ce1460a0b2997e835f37b9/packag es/react-reconciler/src/ReactFiberCommitWork.js#L2583-L2587 ReactはFlowというAltJSで書かれています

Slide 44

Slide 44 text

再掲)Render Phase - completeWork 対象のコード:completeWork 1. createInstanceで実際のDOMの インスタンスを作成 2. appendAllChildrenでサブツリーのDOM Nodeを全 てappendしたDOM Nodeを作成 3. それをstateNodeに代入 completeWorkをFiber Treeを逆に戻るように実行

Slide 45

Slide 45 text

Commit Phase - DOMの挿入

Slide 46

Slide 46 text

Commit Phase - DOMの挿入

Slide 47

Slide 47 text

Commit Phase - DOMの挿入

Slide 48

Slide 48 text

まとめ ● React Componentが宣言的にレンダリング される ● JSXがトランスパイル されReact Elementに変換される ● React Nodeを元にFiber Treeが構築され DOMを操作し、ブラウザにレンダリングされる

Slide 49

Slide 49 text

ご清聴ありがとうございました!