Reactの全体のアーキテクチャ
Reactの構造
- React
ReactDOM.render
Scheduler
合成イベントとは?
達成目標:
Reactが行う処理の全体像をコードベースで掴む。「この処理はどこ?」という疑問に勘所がつく。
ダブルバッファリング等は省略してよいが、循環リストやglobal変数などを丁寧に追う。
.renderがあり、reconciler, react-dom, schedulerなどを行き来する。このワークループを追う?
1. タスクの登録? タスクの登録、スケジューリング
わからない:taskがどこで生成される?render時、rerender時それぞれ。
Schedulerのしくみ
https://gyazo.com/25eb86c16e12824d1b4717b9417a76f7
.render => createUpdate
ensureRootIsScheduled => unstable_scheduleCallback
container.renderはSchedulerを起動させ、タスクを登録する
Schedulerの役割はタスクを優先度順に処理しながら、ブラウザイベントに即座に反応すること
ブラウザイベントに対応するために、5msごとにReactの計算を中断する
締め切りが近い順に計算するために、優先度つきキューで実行タスクを管理する
タスクはperformConcurrentWorkOnRoot
TODO: suspenseとかはどう実行される?shcedulerに登録されるのか?
こぼれ話
Scheduling APIがFacebook提案で入っている。
Reconcilerのしくみ
https://gyazo.com/9ede6da03233d992c1ad51eca1f734fe
performConcurrentWorkOnRootは差分検知・DOMへの更新反映の両方を行う
差分検知はレンダリングフェーズ、DOM更新はコミットフェーズと呼ばれる
短時間で中断可能にするため、再開可能になっている (for ブラウザイベント)
2つのフェーズとして説明されることが多いが、completeUnitOfWorkもフェーズと呼ばれており、@koba04さんのように3つのフェーズがあると説明するのもそこまでおかしくない
Rendering Phase
既知として扱うこと
Fiber
ダブルバッファリング
Rendering Phaseで、Fiberの木構造を深さ優先探索で走査する
Fiberの木構造は、HTMLの木構造にReactコンポーネントが挟まったやつとみなしていい
React Debugger Extentionでみれるやつ
beginWorkで各fiberを計算し、子fiberに移動して次を計算する
ここではこまかいレンダリングの処理は知らなくて良い
関数が実行されて、Fiberに保持される
計算結果がどこに入るかだけ知りたい
Reactコンポーネントでは差分検出
このあたり未知の領域が多い
propsの差分検出と更新としての差分検出は違いあるのか?
関数コンポーネント
hooksはfiberのプロパティに格納される
early bailoutの条件?
Context?
末端nodeではcompleteUnitOfWorkが実行
ほんと?<div><button>hello</button></div>で末端はhelloになるけど、それを指しているのか
ビットマスク(lane)で優先度の高い処理から計算する
Q:優先度の高い処理から計算するとは、実行パスごとに優先度の同じものだけを処理するということ?
reconcileChildrenが差分を検出し、更新を指示する。
Q: どうやって差分を検出する?
Q: 更新はEffect Tagに入る?
ReactDOM.createRoot(container).render(<App/>)で、updateContainerが走り、Schedulerの関数を呼び出す。これは5msごとにレンダリングを中断する。
React Fiber Architectureの2つの特色。レンダリングをより小さな作業単位に分割することで、ブラウザイベントに反応できるようにすること。優先度の概念を導入して、ブラウザイベント以外でも即時性の求められる更新を優先してDOMに反映させること。