React Fiberとは
今更ながらReact Fiberを調べてみました。
実際にReactを書くだけ
なら知らなくても書けてしまいますが、概念や仕組みを知ることでより効率的に記述できることもあると思います。
ということで今回はReact Fiberとは何なのかを備忘録も兼ねて概要をまとめてみます。
React Fiberとは
React FiberとはReact16からの新しいReconciliation Engine
で、古いReconciliation
を完全に後方互換性を持って書き直したものです。レンダリング作業を分割し、複数のフレームに分散させる機能を持っています。
この新しい、Reconciliation Algorithm
はFiber Reconciler
と呼ばれます。
この名前は、DOMツリーのノードを表すのに使われるFiberに由来します。
Reconciliationとは
React Fiber
を理解するにあたってReconciliation
がそもそも何なのかを理解する必要があります。
Reconciliation
とは、Current Tree
(現在の仮想DOM)とWorkInProgress Tree
(新しい仮想DOM)2つのTreeを再起的に比較して差分を計算し、実際のDOMに必要な更新を行うプロセスのことを指します。
React16以降のReconciliation
はFiber Reconciler
と呼ばれ、それ以前のものはStack Reconciler
と呼ばれます。
Stack Reconcilerとは
Fiber Reconciler
が何であるかを理解しやすくするためにStack Reconciler
が何なのかを簡単に説明します。
現在の仮想DOMと新しい仮想DOMを比較し差分を計算する部分においてはどちらも同じですが、Stack Reconciler
は同期的に差分の計算を行っています。これは1つの欠点であり、現在の仮想DOMと新しい仮想DOMの差分検知が行われる間スレッドを占有してしまっていました。
そのため、すべてのイベントは差分検知が終了するまで待機する必要があります。
Fiber Reconcilerとは
Fiber Reconciler
はStack Reconciler
の欠点を解消したAlgorithmで下記のような機能を持ち合わせています。
- 差分検知の作業をFiber単位で行うことができ、複数のフレームに分散できる
- 新しい更新が入ってきた時に作業を一時停止、中断、再利用できる
- 更新をする際に優先順位を割り当てられる
これらのことを行うには作業自体を小さく分解する必要があります。この実行する作業の単位をFiber
と呼びます。
Fiber
実行する作業の単位を表します。React要素はすべてFiber Node
に変換されます。
Fiber Node
は最初のレンダリングでのみ作成され、それ以降は、すでに作成されたFiberがコンポーネントの状態を保持します。
状態の保持に関してはこちら。
また、上述した通り作業を一時停止、中断、再利用を行うために、それぞれのFiberには優先順位が割り当てられます。
Fiber Tree
それぞれのFiberを保持するものをFiber Treeと呼びます。
下記のようなComponentは図1のようなFiber Treeになります。
<div>
<h1>Hello world</h1>
<div>
<p>
hoge
</p>
</div>
</div>
図1
-
child
それぞれのFiberは、最初のComponentへの参照のみ持ちます。図1では黒矢印で表されています。 -
sibling
それぞれのFiberは、次の兄弟への参照を持ちます。図1では青矢印で表されています。 -
return
それぞれのFiberは、親への参照を持ちます。図1では赤矢印で表示されています。
その他のFiber Nodeのプロパティは以下を参考にしてください
このFiber Tree
をトラバースし差分を検知します。トラバースは下記の順番で行なわれます。
-
Start
root要素から開始。そのためのFiberを作成します。 -
Child
親要素から、最初の子要素にトラバースします。これはリーフ要素に到達するまで再起的に行われます。 -
Sibling
リーフ要素に到達すると、その要素に兄弟要素があるかどうかチェックします。もしあれば、Startから開始します。 -
Return
兄弟要素がない場合、親要素に戻ります。
上記のようにそれぞれのFiberが次のFiberへのポインタを持っているため、作業を一時停止したり再開することができるのです。
またこれらの作業は以下のタイミングで実行されます。
-
Initial Render Phase
初期レンダー時。React要素毎にFiberが作成されます。 -
Render Phase
Comoponentの状態変更など、Applicationの全ての更新に対して呼び出されます。このとき現在のCurrent Treeを持っています。新しく作成したツリーをWorkInProgress Treeと呼びます。
このフェーズでは、Current Treeがルートからリーフまでトラバースされ、ツリー内の既存のFiberが更新され、新しいstateとpropで処理されます。このフェーズは非同期であり、現在処理中のFiberの優先度よりも高い優先度で更新されたFiberが間に入ると、その間に中断することができます。
その場合、優先順位の高いタスクが処理されるように、Fiberの処理を停止または中断することができます。 -
Commit Phase
完成したFiber TreeがUIにレンダリングされます。ブラウザのDOMが再描画されるフェースです。
このフェーズは同期的に実行され、一度Commitが始まると中断することはできません。
このフェーズが完了するとWorkInProgress TreeはCurrent Treeとしてマークされます。
まとめ
React Fiberとはレンダリング作業を分割し、複数のフレームに分散させる機能を持った新しいReconciliation Algorithm
だと言うことが分かりました。
他にもScheduling機能やeventに優先順位をつけるのはいつやってるかなどまとめたいことがあるのですが、長くなりそうなので今回は省きました。
また機会があればまとめてみようと思います。
参照
Discussion