React Fiberデータ構造の解明
3392 ワード
このチャプタは、2つの
個人ブログ
まず上の図のノード間の関係をコードで表します.例えば
ノード間のチェーンは次のような3つの状況があります.親ノードからサブノード(赤い点線) 同層ノード(黄色点線) サブノードから親ノード(青い点線) まで
親ノードは第一のサブノードを指し、各サブノードは親ノードを指し、同じ層ノード間は一方向チェーンテーブルである.
まず、ノードのデータ構造を構築することを示します.
最後に残った
Fiber Reconcilerの強み
上記2つのデータ構造のコードを解析することにより、以下の結論が得られる.は、ツリーの深さ巡回に基づいて実現されるReconciler:一旦呼び出しスタックに入ると、停止できなくなる. は、チェーンに基づいて実現されたReconciler: 関連リンク The how and why on React’s usage of linked list in Fiber to walk the component's tree
demo
によってStack Reconciler
およびFiber Reconciler
のデータ構造を示す.個人ブログ
まず上の図のノード間の関係をコードで表します.例えば
a1
の下にb1、b2、b3
があったら、その間の関係をa1.render = () => [b1, b2, b3]
と書いてもいいです.var a1 = { name: 'a1', render = () => [b1, b2, b3] }
var b1 = { name: 'b1', render = () => [c1] }
var b2 = { name: 'b2', render = () => [c2] }
var b3 = { name: 'b3', render = () => [] }
var c1 = { name: 'c1', render = () => [d1] }
var c2 = { name: 'c2', render = () => [] }
var d1 = { name: 'd1', render = () => [d2] }
var d2 = { name: 'd2', render = () => [] }
Stock ReconcilerReact 16
の前に、ノード間の関係は、データ構造
で表されてもよい.walk
関数を以下のように実装し、巡回ノードを印刷します.walk(a1)
function walk(instance) {
if (!instance) return
console.log(instance.name)
instance.render().map(walk)
}
出力結果は:a1 b1 c1 d1 d2 b2 c2 b3
Fiber ReconcilerReact 16
において、ノード間の関係は、データ構造の
で表されてもよい.ノード間のチェーンは次のような3つの状況があります.
親ノードは第一のサブノードを指し、各サブノードは親ノードを指し、同じ層ノード間は一方向チェーンテーブルである.
まず、ノードのデータ構造を構築することを示します.
var FiberNode = function(instance) {
this.instance = instance
this.parent = null
this.sibling = null
this.child = null
}
次に、ノードを直列に接続するconnect
関数を作成する.var connect = function(parent, childList) {
parent.child = childList.reduceRight((prev, current) => {
const fiberNode = new FiberNode(current)
fiberNode.parent = parent
fiberNode.sibling = prev
return fiberNode
}, null)
return parent.child
}
JavaScriptでチェーンを実現するデータ構造は、うまくreduceRightを使うことができます.connect
関数において上記のリンク関係が実現された.このように使えます.var parent = new FiberNode(a1)
var childFirst = connect(parent, a1.render())
これにより、a1
がb1
を指すチェーン、b1、b2、b3
の一方向チェーン、b1、b2、b3
がa1
を指すチェーンが完成した.最後に残った
goWalk
関数は、全てのノードを巡回する.//
var walk = function(node) {
console.log(node.instance.name)
const childLists = node.instance.render()
let child = null
if (childLists.length > 0) {
child = connect(node, childLists)
}
return child
}
var goWalk = function(root) {
let currentNode = root
while (true) {
const child = walk(currentNode)
//
if (child) {
currentNode = child
continue
}
// ,
while (!currentNode.sibling) {
currentNode = currentNode.parent
if (currentNode === root) {
return
}
}
//
currentNode = currentNode.sibling
}
}
//
goWalk(new FiberNode(a1))
印刷結果はa1 b1 c1 d1 d2 b2 c2 b3
です.Fiber Reconcilerの強み
上記2つのデータ構造のコードを解析することにより、以下の結論が得られる.
while(true) {}
のループにおいて、currentNode
の割当値によって操作が必要なノードを再取得することができ、割り当て前に他のロジックを実行することができ、これもrequestIdleCallback
がFiber Reconciler
で動作できる理由である.