1. DOM の違いキー属性の重要性を本当に理解するには、まず DOM Diff から始める必要があります。DOM Diff の原理を深く理解する必要はなく、DOM Diff の動作プロセスを知るだけで十分です。 Vue と React はどちらも仮想 DOM を使用して、不要なブラウザ レンダリングを削減します。 Vue と React はどちらもビューをレンダリングするために v = render(m) メソッドを使用するため、モデル データが変更されると、DOM 要素が再レンダリングされてビューが更新されます。しかし、コンポーネント内の div のデータだけを変更する場合もあります。ネイティブ レンダリングを使用してビューを更新する場合は、コンポーネント全体を更新する必要があります。時間の無駄じゃないですか? 日常生活でこのような状況に遭遇した場合、すべてのピースを更新することはありません。パズルが完成した後、小さなピースの 1 つを交換する必要があるようなものです。ピースを見つけて直接交換するだけです。最初からやり直すことはありません。 Vue と React の開発者も同様に考えており、最適化するためにあらゆる可能な方法を試します。 人間の目には変更前と変更後の違いが一目でわかるので、その違いだけを更新すればいいのです。しかし、コンピューターはそれを一目で見ることはできません。違いを見つけて更新するまで、最初から素早く比較する必要があります。変更前と変更後を比較して相違点を見つけるプロセスを DOM Diff と呼びます。DOM Diff の DOM は仮想 DOM、つまり JavaScript オブジェクトです。1 つずつ比較して相違点を見つけた後、実際の DOM を部分的に更新します。 比較プロセス中に、仮想 DOM も仮想 DOM ツリーを形成します。DOM Diff の動作プロセスは、2 つの仮想 DOM ツリー上のオブジェクト ノードを比較することであり、具体的には各レイヤーの対応する位置を比較します。コンピュータは各レイヤーの対応する位置にある 2 つの仮想 DOM 要素のみを比較するため、2 つのツリー内の変更されたツリーのレイヤーに 1 つのノードのみが挿入された場合、ツリーの構造は変更されず、次の図に示すように、このレイヤーを比較するときに DOM Diff によって不整合な比較が発生します。 このレベルの仮想 DOM ノードは、DOM ノード自体を除いて Vue と React で完全に同じであるため、DOM Diff は比較時に対応する位置を 1 つずつしか比較できません。 1 対 1 の比較後、ノード タイプが同じであれば、ノードは再利用され、ノード内の異なるコンテンツのみが部分的に更新されます。上図に示すように、これが ul の下の li の仮想 DOM ノードである場合、1 つずつ比較してノード タイプが同じであることがわかった後、前のノードが再利用され、ノード内のコンテンツが変更されます。つまり、C は F に更新され、D は C に更新され、E は D に更新され、最後に E が挿入されます。 上記はノードを挿入する場合であり、その結果は効率の低下です。しかし、ノードを削除する場合、結果は効率だけではありません。 li 要素を削除するボタンをクリックすると、新しい仮想 DOM ツリーと古い仮想 DOM ツリーを比較するときに、ツリー内の各レイヤーの対応する位置に従って 1 つずつ比較されます。たとえば、削除後、[1,2,3] は [1,3] になります。最初の li と 2 番目の li を比較します。要素タイプが変更されていないことが判明した場合は、最初の li を再利用し、その中の li を再帰的に比較します。変更がないことが判明した場合は、再利用を続けます。 2 番目の li 要素を比較すると、それらも li 要素であることがわかるため、前の li が再利用され、2 のみが 3 に変更されます。 このとき、再利用された li にサブ要素があり、サブ要素が依存するデータが変更されていない場合、以前のサブコンポーネントが引き続き再利用され、次の図に示すように不整合が発生します。 2. 同じレイヤーの同じタイプの要素にキー属性を追加する上記の DOM Diff アルゴリズムでは、2 つのツリーの同じレイヤーの対応する位置のみが比較されます。異なるレイヤー間の要素を比較する必要はありません。さらに、DOM Diff プロセスで、変更された仮想 DOM が以前の仮想 DOM と異なるタイプであることが判明した場合、以前の仮想 DOM はアンインストールされ、変更された要素ノードが再度追加されます。したがって、2 つのツリー内の同じレイヤーのノード タイプが同じである場合に上記の問題が発生し、レイヤーを追加または削除すると効率が低下したり、バグが発生したりします。 これは、v-for ループで同じタイプのラベル要素を生成すると発生します。ラベル ノードに対して何もしないと、バグが発生するリスクがあります。では、どうすればよいでしょうか。 答えは、同じレイヤーにある同じノード タイプのノードに一意のキー値を追加することです。このようにして、DOM Diff がペアワイズ比較を実行すると、対応する位置に従って比較するのではなく、同じキーを持つ 2 つの仮想 DOM が比較されます。 これにより、不整合な比較が回避され、比較の効率が大幅に向上し、バグのリスクが解決されます。 3. キーはインデックスの添え字値にはならない配列やオブジェクトのインデックス値は一意であるため、キー属性の値としてインデックスを使用することがよくあります。これは問題なく、パフォーマンスの最適化などをもたらすと言う人もいますが、インデックス値を使用すると大きなバグのリスクが発生します。 これらのバグは、v-for ループ内のオブジェクトまたは項目が追加、削除されたり、順序が変更されたりしたときに発生します。 では、なぜインデックス添え字を使用できないのでしょうか? 実は、インデックスの添え字が使われたり使われなかったりするからです。追加や削除をすると、特定の要素のインデックスが変わるからです。例えば、[1,2,3]が[1,3]になった後、データ3に対応する元の添え字は2で、削除後はデータ3の添え字は1になります。DOM Diffを実行すると、等しいキー値に基づいてペアワイズ比較が実行されます。データ3に対応するノードは、まだ互いに対応していません。そのため、インデックスをキーとして使用すると、キーを設定しないのと同じ効果があります。 これが、インデックスをキーとして使用すべきではない理由です。 したがって、キー属性値は一意であり、変更されない必要があります。 上記は、vue における v-for のキー一意性についての詳細な説明です。vue における v-for のキー一意性についての詳細は、123WORDPRESS.COM の他の関連記事にも注目してください。 以下もご興味があるかもしれません:
|
<<: CentOS 7 でゲートウェイを変更して IP を設定する方法の例
>>: MySQLのテーブル構造を変更する際に知っておきたいメタデータロックの詳しい解説
この記事では、例を使用して、CentOS プラットフォーム上で LAMP 環境を迅速に構築する方法に...
目次1. マルチインスタンスとは2. 複数インスタンスのインストールの準備3. MYSQLの複数イン...
-9999 ピクセルの画像置換技術は、ここ 10 年近く人気があります。テキスト要素を画像に置き換え...
IDEA は Java で最も一般的に使用されている開発ツールであり、Docker は最も人気のある...
InnoDB ストレージ エンジンの主な機能には、挿入バッファ、二重書き込み、適応ハッシュインデック...
MySQL スロー ログは、MySQL DBA やその他の開発および運用担当者が細心の注意を払う必要...
これは純粋に CSS のみを使用して作成されたエフェクトです。簡単に言うと、このエフェクトは画像処理...
1. Pythonは起動時に自動的に実行されますPython の自己起動スクリプトがauto.pyで...
<br />友人と話し合っていたとき、フレームワークのレイヤー設計の中で最も核となるのは...
この記事は主に、MySQL インデックスの長さ制限の原理の分析を紹介します。サンプル コードを通じて...
Linux でファイルを見つけたいのに、その場所がわからないことがよくあります。次のコマンドを使用し...
VMWareでUbuntuを再起動した後、インターネットにアクセスできなくなる問題を解決するには、次...
この記事では、一般的な MySQL ストレージ エンジンの機能と使用方法を例を使って説明します。ご参...
WeChatミニプログラムはますます人気が高まっています。多くの大学生が独学で学んでいるのも見てきま...
序文Linux システムの HugePages と Oracle データベースの最適化については、関...