仮想 DOM を使用する理由

導入

フロントエンド開発者であれば、テクノロジ スタックとしてフレームワークを使用したかどうかに関係なく、 VDom としても知られる仮想化の概念Vueについて聞いたことがあるはずです。仮想 DOM は Facebook (現在は Meta と呼ばれています) 技術チームによって最初に提案され、最初は React フレームワークで使用され、その後、仮想 DOM の概念が Vue2.0 で導入されました。仮想 DOM の恩恵を受けてレンダリングされる MVVM フレームワーク ページ:DOM


VDOM.jpg

VDom に入る前に、まず JavaScript の操作DOM方法とパフォーマンスの違いを理解しましょう。

JSでDOMを操作する方法と性能

JavaScript運用にはDOM一般的に次の 2 つの方法が採用されます。

  • ネイティブ コードを通じてJavaScript直接操作しますDOM
  • HTML 文字列のスプライシング + innerHTML による直接操作DOM

ネイティブ操作

当社のフロントエンド開発者が最初に に連絡するとき、ネイティブ JS を使用して操作 (追加、削除、変更、確認、イベント バインディングなど) を行うJavaScript方法を学びます。たとえば、次のようなコードがあります。DOM

<div id="testEle">这是div的文本内容</div>
// 修改div的内容
const ele = documont.querySelector('#testEle');
div.innerText = "使用js-innerText修改dom文本"
// or
div.textContent = "使用js-textContent修改dom文本"

インナーHTML

innerHTML メソッドを使用する

const html = `<div>使用innerHTML</div>`
div.innerHtml = html;

仮想 DOM

ここではまず仮想 DOM とは何かについて説明します。実際、仮想 DOM は です一段用来描述真实的DOM的JavaScript代码(对象)并能根据一定的规则转换成真实的DOM节点
仮想 DOM を使用して HTML を操作する

const virtualDOM = {
    
    
  tag: 'div',
  children: [{
    
     children: '使用虚拟DOM操作html' }]
}
// render 函数将虚拟 DOM 创建为真实 DOM ,并将其插入到文档中
render(virtualDOM)

上記は DOM を操作する 3 つの方法ですが、記述すると多少異なります。以下ではパフォーマンスの問題の分析に焦点を当てます。

性能差比較

まず、宣言する重要な点が 2 つあります。

  • js の操作パフォーマンスは dom よりもはるかに優れており、両者は桁違いです。
  • innerHTML はより複雑であるため、js で dom をネイティブに操作するメソッドでは innerHTML メソッドを削除する必要があります。

最速のパフォーマンス

dom を変更する最も直接的な方法は、ネイティブ メソッドを使用することです。これはパフォーマンスにも最良の選択です。

div.textContent = "使用js-textContent修改dom文本"

dom構造のどの部分を変更する必要があるか、どの内容を変更する必要があるかがわかっているため、jsを直接使用してdomを操作するのが最適です。

仮想DOMのパフォーマンス

DOM仮想 DOM を使用して DOM を操作するのは、実際には仮想化前と仮想化後の違いを調べて更新することです。次のサンプルコードを参照してください。

<!-- 原始的dom代码如下 -->
<div>虚拟DOM修改前</div>
<!-- 修改后的dom代码 -->
<div>虚拟DOM修改后</div>

ここで、仮想DOM最下層は引き続きネイティブ js で操作されますDOMが、変更のためにカプセル化の層を作成したことを述べておく必要があります。したがって、仮想化のパフォーマンスはDOMネイティブ JS 操作DOMのパフォーマンスよりも低いのですが、
なぜここにカプセル化の層を追加する必要があるのでしょうか?
まず第一に、最大のフロントエンド パフォーマンスは DOM の頻繁な操作であることを知っておく必要があります。DOM を頻繁に変更すると、ブラウザがリフローして戻ります。したがって、この抽象化レイヤーは、DOM の差分を計算します。 「頻繁な操作」プロセスで可能になり、最終的には過剰な操作による DOM のパフォーマンスの消費が発生しなくなります。たとえば、DOM 変更中に ABCAD が発生した場合、VDom で AD を直接操作することで、中間の無駄が大幅に削減されますプロセス。フレームワークの観点から見ると、中間層での DOM 操作の抽象化により、開発者は DOM の手動操作から解放され、同時に、より多くの「中間層」に適応してプラットフォームのサポートを強化し、クロスレイヤーを実現できます。フレームワークの基盤となるプラットフォーム。

上記のケースから導き出せる結論は次のとおりです。

  • ネイティブ js 操作のパフォーマンスDOM= js 操作のパフォーマンスDOM;
  • 仮想パフォーマンス =前後の差をDOM調べるための js のパフォーマンス+ js 操作のパフォーマンス。DOMDOM

上記の式によれば、js找出DOM前后差异的性能消費量が 0 の場合にのみ、2 つのパフォーマンスは等しくなりますが、それを超えることはありません。原生js操作DOM的性能そのため、フレームワーク内のアルゴリズムを使用して仮想的なDOM差異を比較すると、それは無限の最適化となり、そのパフォーマンスの消費を最小限に抑える (これが、diff後でアルゴリズムが使用される理由です)
なぜ仮想が依然として使用されるのかについてはDOM、この質問については記事の最後で説明します。

innerHTML のパフォーマンス

innerHTMLこれは単純な割り当てではありません。ページが HTML ドキュメントのコンテンツをレンダリングしたい場合は、まずinnerHTMLコンテンツをDOM構造ツリーに解析してから、それをDOMドキュメント構造に挿入する必要があります。もちろん、古いドキュメント構造は、挿入する前に削除されます。ここにはいくつかの重要な質問があります。

  • 解析DOMツリー
  • 元のDOM構造を削除する
  • 新しいDOM構造を作成する

上記 3 つのキー ポイントは解析DOM结构树js レベルの計算に属し、他の 2 つはDOMレベルの演算計算に属します。

3 つの比較

ここで、次の 3 つのパフォーマンス消費の比較分析を実行します。

操作方法 JSレベル DOMレベル
ネイティブJS 純粋な JS 操作 DOM手術
innerHTML Pure JS 操作の HTML 文字列DOM解析 DOM作成する
バーチャルDOM 仮想を作成するDOM DOM作成する

上の表は、新しいページの作成によるパフォーマンス消費を比較しています。まず、ネイティブ JS メソッド (このメソッドは上で説明したため、最適です) を脇に置いて、 virtual とvirtual の間のパフォーマンス損失の違いのみを比較していますDOMinnerHTML

  • innerHTMLパフォーマンス損失 = js 操作 html 文字列スプライシングのパフォーマンス損失 +DOM作成されたパフォーマンス損失;
  • 仮想DOMパフォーマンスの損失 = 仮想オブジェクトを作成する js のパフォーマンスの損失DOM+DOM作成のパフォーマンスの損失。

ページの作成という次元だけで比較すると、両者のパフォーマンスに大きな違いはないようですが、
別の次元から比較してみましょう: ;更新维度更新ページを
使用するプロセスはinnerHTML、HTML 文字列を再構築し、DOM要素のinnerHTM属性 これは、実際には、テキストを変更しただけであっても、innerHTML属性をリセットする必要があることを示しています。属性のリセットは、古い要素をすべて破棄し、新しい要素を完全に作成することinnerHTMLと同じです。仮想がページをどのように更新するかを見てみましょう。JavaScript オブジェクト ( virtual ) を再作成し、古いものと新しい virtual を比較し、変更された要素を見つけて更新する必要があります。もう 1 つの要因は、ページのコード サイズに関係します。たとえば、ページ サイズが大きくなると、更新時のパフォーマンスの消費も大きくなります。仮想では変更部分を更新する必要がありますが、これは更新する必要があるデータの量に関連しており、ページ サイズとは関係ありません。したがって、ページが大きくなるほどパフォーマンスの消費も大きくなり、仮想パフォーマンスの消費をはるかに超えるという結論になります。DOMDOM
DOMDOMDOM
innerHTMLDOMinnerHTMLDOM

操作方法 JSレベル DOMレベル
ネイティブJS 純粋な JS 操作 DOM手術
innerHTML Pure JS 操作の HTML 文字列DOM解析 破棄DOM+DOM作成 (ページ サイズに関連)
バーチャルDOM 仮想DOM+Diff アルゴリズムを作成する 変更部分の更新はDOM更新データ量に関係します

DOM上記の分析とパフォーマンス消費量の比較によれば、ネイティブ JS < 仮想<であることがわかりますinnerHTMLこの場合、なぜネイティブ JS を使用しないのでしょうか? これにより、別の重要な疑問が生じます可维护性

保守性

ネイティブ JS の操作が最もパフォーマンスが優れていますが、実際のビジネス プロジェクト開発では、ネイティブ JS を直接使用して開発することはほとんどなく、以前はネイティブ JS を使用していましたが、現在は 、 、などを使用してJQueryAngularますこれは主に、開発者の精神的負担が軽減され、迅速な開発とコードのメンテナンスが容易になるためです。VueReact

命令的

ネイティブ JS コードは通常、命令型です。つまり、実行したい操作があれば、指示を発行し、そのプロセスに集中します。典型的な命令型フレームワーク (ライブラリ) は JQuery です。たとえば、ラベル内のテキストを変更したいとします。

$('#divTag').text('修改后的文案')

命令型コードは基本的に、実行したいことをプログラムに伝える命令を次々と実行するものです。className を再度変更したい場合はどうすればよいですか?

$('#divTag').className('add-class')

宣言的

宣言型スタイルでは、結果により多くの注意が払われます。実現のプロセスがどのようなものであるかは気にしません。必要なのは、フレームワークに必要な結果を伝えて、それを実現するのを手伝ってもらうことだけです。同じコードを宣言的な方法で実装してみましょう。

<div id="divTag" class="add-class">修改后的文案</div>

これで希望通りの結果が得られましたが、非常に読みやすいでしょうか? この結果をどのように達成するかについては、通常は気にする必要はありませんが、ここでは、カプセル化を支援するために最下層が依然としてVue命令型コードを使用していることを説明する必要があります。命令形が一番良いです。

要約する

Vue プロジェクトを開発する場合は、テンプレート構文を使用することをお勧めします。これは、テンプレート構文の方が仮想 DOM を直接使用するよりも直感的であるためです (仮想 DOM はテンプレート構文より柔軟です)。テンプレート構文はコンパイラーによって仮想 DOM に変換され、レンダラによって実際の DOM ノードにレンダリングされる必要があります。従来の innerHTML と比較した仮想 DOM の最大の利点は、データ更新セクションです。部分が変更され、パフォーマンスの消費が軽減されます。パフォーマンス消費、コードの保守性、主流フレームワークVue(Reactなどを含む) を比較検討する際に、仮想化の概念が使用されますDOMもちろん、レスポンシブなどもあるので、これは使用理由の一部にすぎません。

おすすめ

転載: blog.csdn.net/gaojinbo0531/article/details/129435763