Diffを理解する前に、Reactの仮想DOMの構造を見てみましょう。 これはHTML構造です <div id="父"> <p class="child">私は子供ですp</p> <div class="child">私は子divです</div> </div> これはReactがHTMLをレンダリングするときのjsコードです。babelで試すことができます。 React.createElement("div", {id: "father"}, React.createElement("p", {class: "child"}, "私は子供pです"), React.createElement("div", {class: "child"}, "私は子divです") ); これはツリー構造であることを示しています。 React は、render メソッドを呼び出すときにツリー (pre と呼ばれる) を作成し、次に render メソッドが呼び出されたときに別のツリー (cur と呼ばれる) を返します。 React は、pre ツリーと cur ツリーの違いを比較して、UI を効率的に更新する方法を決定し、現在の UI が最新のツリー cur と同期されるようにします。 UI を効率的に更新するために、React は次の 2 つの仮定に基づいた O(n) ヒューリスティック アルゴリズムを提案します。 1. 2 つの異なるタイプの要素によって異なるツリーが生成されます。 2. 開発者はキー属性を設定して、異なるレンダリングでどのサブ要素を変更せずに保持できるかをレンダラーに伝えることができます。 差分アルゴリズムレイヤーごとの比較2 つのツリーを比較する場合、React はレイヤーごとに比較し、同じカラー ボックス内の DOM ノードのみを比較します。 まず、2 つのツリーのルート ノードを比較します。ルート ノードの種類によって形状が異なります。ルートノードが異なるタイプの要素である場合、React は元のツリーを破棄して新しいツリーを構築します。たとえば、要素が <a> から <img>、<Article> から <Comment>、または <Button> から <div> に変更されると、完全な再構築プロセスがトリガーされます。 //前に <div> <アプリ/> </div> //後 <p> <アプリ/> </p> React は App コンポーネントを破棄し (そのサブコンポーネントもすべて破棄されます)、新しい App コンポーネント (そのサブコンポーネントを含む) を再作成します。 次の DOM 構造変換: React は、同じレイヤー内のノードの位置の変更のみを単純に考慮します。異なるレイヤー内のノードの場合は、単純な作成と削除のみになります。ルート ノードは、子ノードに A がないことを検出すると、A を直接破棄します。また、D は、余分な子ノード A があることを検出すると、子ノードとして新しい A を作成します。したがって、この構造変換の実際の操作は次のようになります。 A.破棄(); A = 新しいA(); A.append(新しいB()); A.append(新しいC()); D.append(A); このアルゴリズムは少し「粗雑」に見えますが、2 つの異なるタイプの要素が異なるツリーを生成するという最初の仮定に基づいています。 React の公式ドキュメントによると、この仮定によって今のところ重大なパフォーマンスの問題は発生していないそうです。もちろん、これは、安定した DOM 構造を維持することが、独自のコンポーネントを実装する際のパフォーマンスの向上に役立つというヒントも与えてくれます。たとえば、DOM ノードを実際に削除したり追加したりするのではなく、CSS を使用して特定のノードを非表示にしたり表示したりできる場合があります。 同じタイプのコンポーネントを比較するコンポーネントが更新されると、コンポーネント インスタンスは変更されませんが、状態または props のデータが変更されると、render が呼び出され、コンポーネント内の子要素が更新されます。 同じタイプの要素の比較同じタイプの 2 つの React 要素を比較する場合、React は DOM ノードを保持し、変更されたプロパティのみを比較して更新します。 <div className="before" title="内容" /> <div className="after" title="内容" /> React は、div の className を before から after に変更します (React で状態を更新するマージ操作に似ています)。 子ノードを再帰的にデフォルトでは(レベルごとの比較)、DOM ノードの子を再帰的に処理する場合、React は両方の子のリストを同時に走査します。違いが見つかると、ミューテーションが生成されます。 したがって、リストの末尾に要素を追加する場合、更新のオーバーヘッドは比較的小さくなります。例えば: <ul> <li>まず</li> <li>2番目</li> </ul> <ul> <li>まず</li> <li>2番目</li> <li>3番目</li> </ul> React は最初に 2 つの <li>first</li> ツリーを一致させ、次に 2 番目の要素 <li>second</li> のツリーを一致させ、最後に 3 番目の要素の <li>third</li> ツリーを挿入します。 新しい要素をテーブル ヘッダーに単純に挿入すると、更新のオーバーヘッドが比較的大きくなります。例えば: <ul> <li>デューク</li> <li>ヴィラノバ</li> </ul> <ul> <li>コネチカット</li> <li>デューク</li> <li>ヴィラノバ</li> </ul> React は、<li>Duke</li> と <li>Villanova</li> を保持する必要があることに気付かず、それぞれの子を再構築します。この状況はパフォーマンスの問題を引き起こす可能性があります。 キー上記の問題を解決するために、React は key 属性を導入しました。子にキーがある場合、React はそのキーを使用して、古いツリーの子と最新のツリーの子を一致させます。次の例では、キーを追加した後のツリー変換の効率が向上します。 <ul> <li key="2015">デューク</li> <li key="2016">ヴィラノバ</li> </ul> <ul> <li key="2014">コネチカット</li> <li key="2015">デューク</li> <li key="2016">ヴィラノバ</li> </ul> これで、React は「2014」キーを持つ要素だけが新しく、「2015」キーと「2016」キーを持つ要素は単に移動しただけであることを認識します。したがって、key=2014 の要素のみが作成され、残りの 2 つの要素は作成されません。 したがって、配列の順序が変わる可能性があるため、配列の添え字をキー値として使用しないことをお勧めします。データ自体に含まれる一意の識別子 (ID またはその他の属性) を使用するのが最適です。 1. 仮想DOMにおけるキーの役割: 2) 詳細: 状態内のデータが変更されると、React は新しいデータに基づいて新しい仮想 DOM を生成し、新しい仮想 DOM と古い仮想 DOM の diff 比較を実行します。比較ルールは次のとおりです。 a. 新しい仮想 DOM と同じキーが古い仮想 DOM に見つかります。 b. 新しい仮想DOMと同じキーが古い仮想DOMに見つからない 2. インデックスをキーとして使用する場合に発生する可能性のある問題: 2. 構造に入力クラスの DOM も含まれている場合: 上記は、React Diff 原則の徹底的な分析の詳細な内容です。React Diff 原則の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: Ubuntu 18.04 が VMware 仮想マシンでネットワークに接続できない問題の解決策
目次1. Jquery を使用する手順: (1)jsライブラリをインポートする(2)ページ読み込みイ...
序文ブロガーはアイデアIDEを使用しています。アイデア公式が最近サードパーティのアクティベーションサ...
Anaconda は、conda、Python、およびそれらの依存関係など、180 を超える科学パッ...
mysql5.6 のグリーン バージョンを解凍すると、my-default.ini ファイルが作成さ...
この記事では、キャンバスを使用して画像圧縮アップロードを実現するVueの具体的なコードを参考までに共...
Ubuntu 20.04 をインストールした後、デフォルトでは root アカウントのログイン権限が...
前回の記事では、nginx がリクエスト ラインのデータを読み取って、リクエスト ラインを解析する方...
目次1. 開発環境から本番環境への移行2. 統一されたリクエストパスを設定する3. パッケージ化コマ...
目次1. はじめに2. axiosインターセプターを使用してフロントエンドログを出力する1. はじめ...
この記事では、MySQL クラスター化インデックスのページ分割を例を使って説明します。ご参考までに、...
まずはレンダリングを見てみましょう: XML/HTML コードコンテンツをクリップボードにコピー&l...
目次序文: 1. インデックスメソッドを作成する2. インデックスを作成するために必要な権限序文: ...
序文MySQL では、クロスデータベース クエリは主に 2 つの状況に分けられます。1 つは同じサー...
Docker の基本的な操作を学習した後、コンテナにいくつかの基本的なアプリケーションをデプロイして...
Mac 最新バージョンの MySQL 8.0.22 パスワード回復問題の説明:昨日、突然、Macで最...