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 仮想マシンでネットワークに接続できない問題の解決策
オープンソース データベース アーキテクチャの設計原則01. 技術の選択最も使い慣れていて、最大限に...
この記事を書いている時点でのReactのバージョンは16.13.1です1 npm run eject...
この記事では、JS掃海プロジェクトの概要を参考までに紹介します。具体的な内容は次のとおりです。プロジ...
この記事の例では、簡単なショッピングカート機能を実現するためのjsの具体的なコードを参考までに共有し...
1. Logrotateツールの紹介Logrotate はログファイル管理ツールです。Linux に...
1: タグセレクタータグセレクターはすべてのタグに使用されます。ここでは p を例に挙げます。つまり...
目次導入効果のデモンストレーションは次のとおりです。 MChat コンポーネントのレンダリング: I...
会社の影響力が拡大し、製品が改良され続けるにつれて、関連するイメージデザインもそれに追いつき、徐々に...
成果を達成する実装コードhtml <div class="コンテナ">...
IE で CSS3 を使用して角を丸くする方法を探していたときに、例を見つけました。まだテストして...
実験環境最小限にインストールされた CentOS 7.3 仮想マシン基本環境を構成する1. ngin...
目次1. コンテナ相互接続を実現するためにネットワークをカスタマイズする2. ネットワーク接続1. ...
ソース ファイルを右クリックすると、次のコードが見つかります。 1. CSSを使用してFirefox...
仮想マシンの IP アドレスを変更します。 次のインターフェイスに入り、サブネット IP を直接変更...
目次1. React.Children.map 2. React.Children.forEach ...