React Fiberの仕組みの詳細な説明

React Fiberの仕組みの詳細な説明

React Fiberとは何ですか?

簡単に言えば、React Fiber は、仮想 DOM の増分レンダリングを実装するために React v16 で導入された新しい調整エンジンです。

簡単に言えば、React ビューの更新プロセスをよりスムーズにできる処理方法です。

私たちは皆知っていますが、プロセスは大きく、スレッドは小さいです。繊維は糸よりも細かい粒度を持つ加工機構です。この言葉から、React Fiber が非常に「薄い」ことも推測できます。詳細を確認するために読み進めてみましょう。

なぜReact Fiberなのか?

前述したように、React Fiber は React のビュー更新プロセスをよりスムーズにするように設計されています。なぜですか? 以前は React ビューの更新がスムーズではありませんでしたか?

それは本当です。React v16 より前では、React のビュー更新には大きなパフォーマンスの問題がありましたが、最も顕著だったのは同期更新メカニズムでした。

React がコンポーネント ツリーをロードまたは更新することを決定する前に、おおよそ次の一連のアクションを実行します: 各コンポーネントのライフサイクル関数を呼び出す --> 仮想 DOM を計算して比較する --> 実際の DOM ツリーを更新する。このプロセスは同期的です。つまり、プロセスが開始されると、実際の DOM ツリーが更新されるまで、一度に実行されます。

ただし、コンポーネント ツリーが大きい場合、このメカニズムは問題になります。300 個のコンポーネントを含むコンポーネント ツリーを完全に更新する必要があります。コンポーネントの更新に 1 ミリ秒しかかからないと仮定すると、ツリー全体を更新するには 300 ミリ秒かかります。この 300 ミリ秒の期間中、ブラウザのメイン スレッドはコンポーネント ツリーの更新に「集中」しており (この時点では関数呼び出しスタックが非常に長くなります)、ページ上の操作には「無関心」です。この期間中に、ユーザーが入力ボックスにいくつかの単語を入力しても、ページに応答はありません。これは、キー入力結果のレンダリングにもメイン スレッドが必要であり、この時点でメイン スレッドはコンポーネント ツリーの更新でビジー状態になっているためです。 300 ミリ秒後、ブラウザのメイン スレッドは入力ボックスに入力された単語を自由にレンダリングできるようになります。

本当にラグが多すぎます。

JavaScript のシングルスレッド動作特性のため、業界では常に次のような原則があります。つまり、どのアクションもメインスレッドを長時間占有してはならないということです。メインスレッドが長時間返されない場合、プログラムはこの期間中に他の入力に応答できなくなります。入力後に応答がない、または応答が非常に遅い場合、これを「ラグ」と呼ぶことがあります。明らかに、コンポーネント ツリーが巨大な場合、React の同期更新メカニズムはこの原則に違反します。これは大きなタブーです。

React Fiber が誕生した理由は、古い React ビュー更新のパフォーマンスのボトルネックを解決するためです。

React Fiberはどのように機能しますか?

まず、React Fiber は、大規模なコンポーネント ツリーの更新に時間がかかるという問題を解決しません。実際、総所要時間は依然として同じです。しかし、これは多くの開発者から批判されてきた、メインスレッドを長時間占有するという問題を解決します。

解決策は、シャーディングです。

その動作原理は次のとおりです。時間のかかる更新タスクを小さなタスク スライスに分割し、実行後に各小さなタスク スライスをメイン スレッドに返して、他に緊急に実行する必要があるタスクがあるかどうかを確認します。メイン スレッドに戻るときに緊急タスクが見つかった場合は、現在の更新タスクは直ちに停止され、代わりにメイン スレッドに緊急タスクを実行するように要求されます。メイン スレッドは緊急タスクを完了すると、更新タスクを再度実行します。 (注意⚠️: 最初からやり直すことです。最後に中断した時点から続行するのではありません)。緊急のタスクがない場合は、次のタスク スライスを続行することを敢えてします。

簡単に言えば、ビュー更新の優先度を下げ、更新プロセスを断片化します。

それでは、React Fiber が更新プロセスをどのように処理するかを見てみましょう。

  1. 更新プロセスは、調整フェーズとコミット フェーズに分かれています。調整フェーズ (スケジュール フェーズ) では、データを更新して新しい仮想 DOM を生成し、古い仮想 DOM と新しい仮想 DOM の差分を実行して、更新する必要がある要素を取得し、新しい更新キューに入れます。コミット フェーズ (レンダリング フェーズ) では、更新キューを走査して、実際の DOM へのすべての変更を一度に更新します。
  2. 調整フェーズはシャードに分割されます。このフェーズはより緊急なタスクによって中断される可能性があり、シャードされたタスクは途中で再開する必要がある場合があります。
  3. コミット フェーズでは、DOM は一度に更新され、中断することはできません。

React Fiberの実装原理

React Fiber を実装する際には 2 つの困難があります。一時停止/再開をどのように実装するか?タスクをどのように分配しますか?

前者の場合、一時停止/再開は状態を保存する必要があることを意味します。ここでは、リンク リストとポインターを使用した「単一のリンク リスト ツリー トラバーサル アルゴリズム」が実装で使用され、トラバーサル プロセスの前のステップと次のステップが記録されます。

後者の場合、 requestAnimationFramerequestIdelCallback 2 つの API が使用されます。このうち、 requestAnimationFrameはブラウザによってフレームごとに実行され、いくつかの高優先度タスクをそこに配置できます。一方、 requestIdelCallbackは、フレームの最後に空き時間がある場合にのみブラウザによって実行され、いくつかの低優先度タスクをそこに配置できますが、ポリフィルが必要です (互換性が低いため)。

React Fiber は私たちの日常の開発にどのような影響を与えるのでしょうか?

React Fiber は、調整フェーズ中に次のライフサイクル関数を呼び出す場合があります (つまり、この段階のライフサイクル関数は、ロードおよび更新プロセス中に複数回呼び出される場合があります)。

  • componentWillMount
  • componentWillUpdate
  • componentWillReceiveProps
  • shouldComponentUpdate

開発に React フックを使用せず、従来のクラス コンポーネントを使用する場合は、上記のライフサイクル関数で 1 回だけ実行する必要がある操作 (たとえば、ページの初期化時にデータを取得するための Ajax リクエストを開始するなど) を実行しないようにしてください。

通常、開発に React Hooks を使用している場合は、楽しみのために見るだけで問題ありません。

以上がReact Fiberの仕組みの詳しい説明です。React Fiberの仕組みについてさらに詳しく知りたい方は、123WORDPRESS.COM内の他の関連記事もぜひご覧ください!

以下もご興味があるかもしれません:
  • ES6 クラスチェーン継承、インスタンス化、React Super (props) 原則の詳細な説明
  • react-redux における connect の使い方と原理分析の詳細な説明
  • React-router 4 オンデマンドロードの実装と原理の詳細な説明
  • Reactの原理の説明

<<:  Ubuntuがネットワークに接続できない場合の解決策

>>:  winx64 での mysql5.7.19 の基本的なインストール プロセス (詳細)

推薦する

Dockerでローカルマシン(ホストマシン)にアクセスする方法

質問Docker でローカル データベースにアクセスするにはどうすればよいでしょうか? 127.0....

MySQL におけるデータタイムとタイムスタンプの違い

MySQL には 3 つの日付型があります。日付(年-月-日)テーブル test(hiredate ...

Linux の一般的な Java プログラム起動スクリプトのコード例

シェルを起動する頻度は非常に低いですが。 。 。しかし、書くたびに、多くの jar ファイル パスを...

3Dカルーセル効果を実現するjs

この記事では、3Dカルーセル効果をjsで実装するための具体的なコードを参考までに共有します。具体的な...

CSS ピクセルとさまざまなモバイル画面適応の問題に対する解決策

ピクセル解決通常、モニター解像度と呼ばれるものは、実際にはモニターの物理的な解像度ではなく、デスクト...

Windows Server のインストール後にワイヤレスとオーディオが機能しない問題を解決する

1. ワイヤレスPowerShell を実行し、次のコマンドを入力します。 install-wind...

MySql インデックスの詳細な紹介と正しい使用方法

MySql インデックスの詳細な紹介と正しい使用方法1. はじめに:インデックスはクエリ速度に重大な...

Docker+nextcloudで個人用クラウドストレージシステムを構築

1. Dockerのインストールと起動 yum で epel-release をインストールします ...

Webデザインチュートリアル(2):模倣と盗作について

<br />前回の記事では、Webデザインの手順と方法を紹介しました。詳細については、前...

JS での矢印関数と this の記述と理解

目次序文1. JSで関数を書く方法1. 通常の関数の書き方2. 矢印関数の書き方2. 通常の関数でこ...

MySQLの関連ロックについての簡単な理解

この記事は主にInnoDBのロックに関する知識を素早く理解してもらうことを目的としています。 Roc...

Node.js でメモリ効率の高いアプリケーションを作成する方法

目次序文問題: 大きなファイルのコピーNodeJS のストリームとバッファバッファストリーム解決策 ...

JavaScript の手ぶれ補正とスロットリングの詳細な説明

目次デバウンススロットル要約するデバウンス定義: スクロール イベントなど、短時間に連続してトリガー...

JavaScript スクリプトが実行されるタイミングの詳細な説明

JavaScript スクリプトは HTML 内のどこにでも埋め込むことができますが、いつ呼び出され...

LeetCode の SQL 実装 (182. 重複するメールボックス)

[LeetCode] 182.重複メールPerson という名前のテーブル内のすべての重複メールを...