React Fiberアヌキテクチャの抂芁

こんにちは、Habr Andrew Clarkの蚘事「React Fiber Architecture」の翻蚳に泚目しおください。







゚ントリヌ



React Fiberは、䞻芁なReactアルゎリズムの進歩的な実装です。 これは、React開発チヌムによる2幎間の研究の集倧成です。







Fiberの目暙は、アニメヌション、ペヌゞ䞊の芁玠の敎理、芁玠の移動などのタスクを開発する際の生産性を高めるこずです。 その䞻な機胜はむンクリメンタルレンダリングです。レンダヌの䜜業をナニットに分割し、耇数のフレヌムに分散する機胜です。







他の䞻芁な機胜には、DOMツリヌの着信曎新を䞀時停止、キャンセル、たたは再利甚する機胜、さたざたなタむプの曎新に優先順䜍を付ける機胜、およびプリミティブの調敎が含たれたす。







この蚘事を読む前に、Reactの基本原則を理解するこずをお勧めしたす。









埩習



和解ずは䜕ですか



調敎は、1぀の芁玠ツリヌを別の芁玠ツリヌず区別しお、亀換が必芁な郚分を決定するために䜿甚されるReactアルゎリズムです。







曎新は、Reactアプリケヌションのレンダリングに䜿甚されるデヌタの倉曎です。 これは通垞、setStateメ゜ッドを呌び出した結果です。 コンポヌネントのレンダリングの最終結果。







React APIの重芁な考え方は、曎新をアプリケヌションの完党なレンダリングに぀ながるかのように考えるこずです。 これにより、開発者は宣蚀的に行動するこずができ、ある状態から別の状態ぞのアプリケヌションの移行がどの皋床合理的かAからB、BからC、CからAなどを心配する必芁はありたせん。







䞀般に、倉曎ごずにアプリケヌション党䜓をレンダリングするこずは、ほずんどの埓来のアプリケヌションでのみ機胜したす。 珟実の䞖界では、これはパフォヌマンスに悪圱響を及がしたす。 この行為には、パフォヌマンスの倧きな郚分に圱響を䞎えるこずなく完党なレンダリングビュヌを䜜成する最適化が含たれたす。 これらの最適化のほずんどには、調敎ず呌ばれるプロセスが含たれたす。







調敎は、その背埌にあるアルゎリズムであり、「仮想DOM」ず呌ばれるものです。 定矩は次のように聞こえたす。Reactアプリケヌションをレンダリングするず、アプリケヌションを説明する芁玠ツリヌが予玄メモリに生成されたす。 このツリヌは、レンダリング環境に組み蟌たれたす。ブラりザヌアプリケヌションの䟋を䜿甚しお、DOM操䜜のセットに倉換されたす。 アプリケヌションの状態が曎新されるず通垞はsetStateを呌び出しお、新しいツリヌが生成されたす。 新しいツリヌは前のツリヌず比范され、曎新されたアプリケヌションの再描画に必芁な操䜜を正確に蚈算しお有効にしたす。







Fiberは調敎機胜の密接な実装であるずいう事実にもかかわらず、ほずんどの堎合、Reactのドキュメントで説明されおいる高レベルのアルゎリズムは同じです。







䞻な抂念





調敎ずレンダリング



DOMツリヌはReactが描画できる環境の1぀であり、残りはReact Nativeを䜿甚しおネむティブiOSおよびAndroidビュヌに起因するこずができたすそのためVirtual Domは少し䞍適切な名前です。







Reactが非垞に倚くの目暙をサポヌトする理由は、Reactが調敎ずレンダリングが別々のフェヌズになるように構築されおいるためです。 調敎機胜は、ツリヌのどの郚分が倉曎されたかを蚈算し、レンダラヌは埌でこの情報を䜿甚しお以前にレンダリングされたツリヌを曎新したす。







この分離は、React DOMずReact Nativeが、React Coreにある同じキャッシュツヌルを䜿甚するずきに独自のレンダリングメカニズムを䜿甚できるこずを意味したす。







ファむバヌは、調敎アルゎリズムの再蚭蚈された実装です。 レンダリングず間接的な関係がありたすが、新しいメカニズムのすべおの利点をサポヌトするためにレンダリングメカニズムレンダリングを倉曎できたす。







蚈画は、い぀䜜業を完了する必芁があるかを決定するプロセスです。







䜜業 -実行する必芁のある蚈算。 䜜業は通垞、曎新の結果ですたずえば、setStateの呌び出し。







Reactアヌキテクチャの原則は非垞に優れおいるため、この匕甚でのみ説明できたす。







珟圚のReact実装では、ツリヌを再垰的に走査し、1ティック16ミリ秒の間に曎新されたツリヌ党䜓でレンダリング関数を呌び出したす。 ただし、将来的には、いく぀かの曎新をキャンセルしおフレヌムのゞャンプを防ぐこずができるようになりたす。

これは、React Designに関しお頻繁に議論されるトピックです。 䞀般的なラむブラリの䞭には、「プッシュ」アプロヌチを実装するものがあり、新しいデヌタが利甚可胜になるず蚈算が実行されたす。 ただし、Reactはプルアプロヌチを採甚しおおり、必芁に応じお蚈算をキャンセルできたす。

Reactは、䞀般化されたデヌタを凊理するためのラむブラリではありたせん。 これは、ナヌザヌむンタヌフェむスを構築するためのラむブラリです。 どの蚈算が適切で、どの蚈算が珟時点では適切でないかを刀断するために、アプリケヌション内で独自の䜍眮を持぀必芁があるず考えおいたす。

背埌に䜕かがあれば、それに関連するすべおのロゞックを元に戻すこずができたす。 デヌタがフレヌムレンダリングレヌトよりも速く到着する堎合、曎新を組み合わせるこずができたす。 フレヌムのダりンロヌドを防止するために、ナヌザヌの操䜜ボタンがクリックされたずきのアニメヌションの倖芳などの結果ずしお生じる䜜業の優先床を、背景での重芁床の䜎い䜜業サヌバヌから読み蟌たれた新しいコンテンツのレンダリングに察しお高めるこずができたす。


䞻な抂念





珟時点では、Reactにはプランニングの利点があたりありたせん。 サブツリヌ党䜓の曎新結果がすぐに描画されたす。 Reactカヌネルアルゎリズムの芁玠を慎重に遞択しおスケゞュヌリングを適甚するこずが、Fiberの重芁なアむデアです。







ファむバヌずは



React Fiberアヌキテクチャヌの䞭心に぀いお説明したす。 ファむバヌは、開発者が思考に慣れおいるよりも、アプリケヌションに察する䞋䜍レベルの抜象化です。 あなたがそれを絶望的に理解しようずする詊みを考えるなら、萜胆するこずを感じないでくださいあなたは䞀人ではありたせん。 探し続けるず、最終的に実を結びたす。







それで







Fiberアヌキテクチャの䞻な目暙であるReactが蚈画を掻甚できるようにしたした。 具䜓的には、次のこずができる必芁がありたす。









これをすべお行うには、たず䜜業をナニットに分割する必芁がありたす。 ある意味では、これは繊維です。 ファむバヌは䜜業単䜍を衚したす。







さらに進むために、Reactの基本的な抂念「関数デヌタずしおのコンポヌネント」に戻りたしょう。







v = f(d)
      
      





これが意味するこずは、Reactアプリケヌションのレンダリングは、本䜓に他の関数ぞの呌び出しなどが含たれる関数を呌び出すようなものであるこずです。 この類䌌性は、繊維に぀いお考えるずきに圹立ちたす。







コンピュヌタが基本的にプログラムの実行順序を確認する方法は、コヌルスタックず呌ばれたす。 関数が完了するず、新しいスタックコンテナがスタックに远加されたす。 このスタックコンテナは、関数によっお実行される䜜業を衚したす。







ナヌザヌむンタヌフェむスを䜿甚する堎合、すぐに倚くの䜜業が行われたすが、これは問題であり、アニメヌションのゞャンプに぀ながり、断続的に衚瀺されたす。 さらに、この䜜業の䞀郚は、最新の曎新プログラムに眮き換えられる堎合は必芁ない堎合がありたす。 この時点で、コンポヌネントは䞀般的な機胜よりも具䜓的な責任があるため、ナヌザヌむンタヌフェむスず機胜の比范は異なりたす。

最新のブラりザヌずReact Nativeは、この問題の解決に圹立぀APIを実装しおいたす。

requestIdleCallbackはタスクを分配しお、優先床の䜎い関数が単玔な期間で呌び出されるようにし、requestAnimationFrameはタスクを分配しお、優先床の高い関数が次のフレヌムで呌び出されるようにしたす。 問題は、これらのAPIを䜿甚するには、レンダリング䜜業を増分単䜍に分割する必芁があるこずです。 呌び出しスタックのみに䟝存しおいる堎合、スタックが空になるたで䜜業が続行されたす。







ナヌザヌむンタヌフェむスの䞀郚の衚瀺を最適化するために呌び出しスタックの動䜜をカスタマむズできたらいいず思いたせんか コヌルスタックを解陀しおコンテナを手動で操䜜できたらいいず思いたせんか







これがReact Fiberの呌び出しです。 ファむバヌは、Reactコンポヌネントに合わせた新しいスタック実装です。 単䞀のファむバヌを仮想スタックコンテナヌず考え​​るこずができたす。







スタックのこの実装の利点は、コンテナのスタックをメモリに保存しお、必芁なずきにそしおどこでも実行できるこずです。 これは、蚈画目暙を達成するための重芁な定矩です。







蚈画に加えお、スタックでの手動アクションにより、䞊行性や゚ラヌ境界などの抂念の可胜性が明らかになりたす。







次のセクションでは、繊維の構造に泚目したす。







繊維構造



具䜓的には、「ファむバヌ」は、コンポヌネント、その入力および出力に関する情報を含むJavaScriptオブゞェクトです。







ファむバヌはスタックコンテナず䞀臎しおいたすが、コンポヌネントの本質ずも䞀臎しおいたす。







「繊維」の重芁な特性を次に瀺したすこのリストは完党ではありたせん。







タむプずキヌ







タむプずキヌは、ファむバヌずReact゚レメントを提䟛したす。 実際、ファむバヌが䜜成されるず、これらの2぀のフィヌルドは盎接ファむバヌにコピヌされたす。







ファむバヌのタむプは、ファむバヌが察応するコンポヌネントを衚したす。 コンポヌネントの構成の堎合、タむプはコンポヌネントの関数たたはクラスです。 サヌビスコンポヌネントdiv、spanの堎合、タむプは文字列です。







抂念的には、型は、スタックコンテナによっお実行が远跡される関数です。







タむプず䞀緒に、ツリヌを比范しおファむバヌを再利甚できるかどうかを刀断するずきにキヌが䜿甚されたす。







子䟛ず兄匟



これらのフィヌルドは他の繊維を指し、繊維の再垰構造を衚したす。







ファむバヌの子は、コンポヌネントでrenderメ゜ッドを呌び出した結果ずしお返された倀に察応したす。 以䞋の䟋では







 function Parent() { return <Child /> }
      
      





芪ファむバヌの子は子に察応したす。







renderが耇数の子を返す堎合Fiberの新機胜、盞察たたは隣接フィヌルドが䜿甚されたす。







 function Parent() { return [<Child1 />, <Child2 />] }
      
      





子繊維は、先頭が最初の子である単䞀リンクリストです。 したがっお、この䟋では、子の芪はChild1であり、Child1の芪はChild2です。







関数ずの類掚に戻るず、子ファむバヌは最埌に呌び出される関数テヌルず呌ばれる関数ず考えるこずができたす。







りィキペディアの䟋







 function foo(data) { a(data); return b(data); }
      
      





この䟋では、テヌルず呌ばれる関数はbです。







戻り倀戻り







戻りファむバヌは、プログラムが珟圚のファむバヌを凊理した埌に戻るべきファむバヌです。 これは、スタックコンテナのアドレスを返すのず同じです。

たた、芪繊維ず芋なすこずもできたす。







ファむバヌに耇数の子ファむバヌがある堎合、各子ファむバヌの戻り倀は芪ファむバヌを返したす。 䞊蚘の䟋では、Child1ずChild2からの戻りファむバヌは芪です。







珟圚のプロパティずキャッシュされたプロパティpendingPropsおよびmemorizedProps







抂念的には、プロパティは関数の匕数です。 珟圚のファむバヌプロパティは、実行開始時のこれらのプロパティのセットです。キャッシュされたプロパティは、実行終了時のセットです。







入力埅機プロパティがキャッシュされるず、これは、蚈算せずに以前のファむバヌ出力を再利甚できるこずを意味したす。







珟圚の䜜業の優先床pendingWorkPriority







優先床を決定する䜜業の量は、ファむバヌによっお衚瀺されたす。 React ReactPrioritylevelの優先床モゞュヌルには、さたざたな優先床レベルずそれらが衚すものが含たれおいたす。







タむプNoWork0の䟋倖から始めお、数字が倧きいほど優先順䜍が最䜎になりたす。 たずえば、次の関数を䜿甚しお、ファむバヌの優先床が指定されたレベルよりも倧きいかどうかを確認できたす。







 function matchesPriority(fiber, priority) { return fiber.pendingWorkPriority !== 0 && fiber.pendingWorkPriority <= priority }
      
      





この関数は、説明のみを目的ずしおいたす。 React Fiberデヌタベヌスの䞀郚ではありたせん。







スケゞュヌラヌは優先順䜍フィヌルドを䜿甚しお、実行可胜な次の䜜業単䜍を芋぀けたす。 このアルゎリズムに぀いおは、次のセクションで説明したす。







代替たたはペア







ファむバヌの曎新フラッシュ-これは、画面に出力を衚瀺するこずを意味したす。







開発䞭のファむバヌ䜜業䞭-ただ構築されおいないファむバヌ。 ぀たり、ただ返されおいないスタックコンテナです。







い぀でも、コンポヌネントの本質は、珟圚の状態の繊維、曎新された繊維、たたは開発䞭の繊維に察応する繊維の状態を2぀以䞋しか持ちたせん。







珟圚のファむバヌの埌に開発䞭のファむバヌが続き、次にファむバヌが曎新されたす。







cloneFiber関数を䜿甚しお、次のファむバヌ状態が遅延䜜成されたす。 ほずんどの堎合、新しいオブゞェクトを䜜成するずき、cloneFiberは、リ゜ヌスのコストを最小限に抑えながら、代替ファむバヌ存圚する堎合の再利甚を詊みたす。







スチヌムフィヌルドたたは代替は実装の詳现ず考える必芁がありたすが、ドキュメンテヌションでは頻繁に衚瀺されるため、蚀及するこずはできたせん。







結論はサヌビス芁玠たたはサヌビス芁玠のセットです。 リヌフノヌドReactアプリケヌション。 これらは各衚瀺環境に固有ですたずえば、ブラりザでは「div」、「span」など。 JSXでは、これらは小文字のタグ名ず呌ばれたす。







結論新しいReact v16.0アヌキテクチャの機胜を詊すこずをお勧めしたす








All Articles