色々素敵な記事が既に存在してはいますが、自分自身の理解を深めたく、React FiberのFiberとはなんなのか勉強してみたものをまとめました。
尊敬の念を込めて、大変勉強になった素晴らしい記事たちを先に紹介しときます。
###解説しないこと
- Fiber以外のReact ver.16以降での変更点
- あくまでFiberとはなんなのかにフォーカスします。
- (ただ個人的には
render()
の結果を文字列や配列で返せるようになるのは超嬉しいです。)
React Fiberを理解するための前提知識
React Fiberを理解するにあたって重要なキーワードは次の3つです。
- リコンシリエーション
- 作業
- スケジューリング
FiberはReactのリコンシリエーションの新しいアルゴリズムです。
このためFiberとは何ぞやを理解するためにはリコンシリエーションとは何ぞやを理解する必要があります。
###リコンシリエーションとは
端的に言うと「どの部分に変更が必要か判断すべく、ツリー同士の差分を出すアルゴリズム」です。
詳しくはReactのドキュメントにまとまっていますが、
簡単に解説すると、Reactはご存知の通りVirtual DOMを内部的に保持しており、Stateの更新が起きた時に、
以前のVirtual DOMとStateの更新によって変更が入ったVirtual DOMのdiffを取って最小限のリアルなDOMの更新をするように努めています。
このdiffの取り方・アルゴリズムこそがリコンシリエーションです。
特に重要なポイントとしては以下の2点が挙げられます。
- コンポーネントの種類が異なると、生成されるツリーも大幅に異なったものになることが想定される。そのような場合、Reactは差分を出すのではなく、元のツリーを完全に置き換えようとする。
- リストの差分計算は、キーを使って実行される。キーは「安定性があり、予測でき、一意である」ことが求められる。
###作業とスケジューリングとは
- 作業
- 実行されなければならない計算。作業は通常、更新(例えばsetState)の結果として生じる。
- スケジューリング
- 作業が実行されるべきタイミングを判断するプロセス。
スケジューリングは基本的に更新処理のタイミングを決定するためのものであり、そしてこれがFiberというものが必要になった原因なのですが、
従来のReactでは「仮想DOMのツリーを上から再帰的に比較していく」というスケジューリングの仕方がなされていました。
これの何が問題なのかと言うと
「リコンシリエーションによって更新が決定したもの全ての更新処理が終わるまで他の処理をブロックしてしまい、また中断することもできない」という点です。
UI上では必ずしも全ての更新が即座に適用される必要はありません。
更新処理が多くなると、即座に更新する必要のない部分の更新のために画面がフリーズしてしまい、ユーザ体験を阻害する恐れがあります。
これをよしとせず、すぐに更新しなければいけない部分とそうでない部分を分けて、
ユーザ体験に重要な部分に対して優先度を付けられるようにしよう、というのがReact Fiberが実現しようとしていることです。
Fiberとは
前の項でそこそこ概要を説明してしまった気もしますが、
初めにFiberという言葉自身の定義を述べると 作業の構成単位
という意味になります。
先の項で述べたようにReact Fiberは「更新処理に優先度が付けられるようにする」ことを目指したものです。
それを実現するために以下のようなことを実行しています。
- リコンシリエーションをツリー全体に対してではなく、Fiberの単位で実行する
-
ReactElement
毎の更新処理をLinked Listにして、それぞれを独立したものとして扱えるようにしている
-
-
requestIdleCallback()
やrequestAnimationFrame()
を使って、優先度付きのスケジューリングを擬似的に行う-
requestIdleCallback()
を使って指定されたFiberはブラウザの処理がひまになった時に実行される -
requestAnimationFrame()
を使って指定されたFiberは優先度が高く、できるだけ早いタイミングで実行される
-
まとめるとFiber単位での優先度付きスケジューリングが可能になるよ、ということですね。
スケジューリングの具体的な仕方についてはこちらの記事が詳しいため、知りたい場合はご覧になることをお勧めします。
まとめ
フロントエンド開発において「いかにUIをブロックせずにユーザ体験に大切なところだけを表示するか」
というのは重要な命題なので、Reactのリコンシリエーションのレベルで直接優先度付けできるようになったというのは、
アプリケーションによっては大きなメリットになりえるのかなと思いました。