導入
フロントエンド開発者であれば、テクノロジ スタックとしてフレームワークを使用したかどうかに関係なく、 VDom としても知られる仮想化の概念Vue
について聞いたことがあるはずです。仮想 DOM は Facebook (現在は Meta と呼ばれています) 技術チームによって最初に提案され、最初は React フレームワークで使用され、その後、仮想 DOM の概念が Vue2.0 で導入されました。仮想 DOM の恩恵を受けてレンダリングされる MVVM フレームワーク ページ:DOM
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 操作のパフォーマンス。DOM
DOM
上記の式によれば、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 の間のパフォーマンス損失の違いのみを比較していますDOM
。innerHTML
innerHTML
パフォーマンス損失 = js 操作 html 文字列スプライシングのパフォーマンス損失 +DOM
作成されたパフォーマンス損失;- 仮想
DOM
パフォーマンスの損失 = 仮想オブジェクトを作成する js のパフォーマンスの損失DOM
+DOM
作成のパフォーマンスの損失。
ページの作成という次元だけで比較すると、両者のパフォーマンスに大きな違いはないようですが、
別の次元から比較してみましょう: ;更新维度
更新ページを
使用するプロセスはinnerHTML
、HTML 文字列を再構築し、DOM
要素のinnerHTM
属性 これは、実際には、テキストを変更しただけであっても、innerHTML
属性をリセットする必要があることを示しています。属性のリセットは、古い要素をすべて破棄し、新しい要素を完全に作成することinnerHTML
と同じです。仮想がページをどのように更新するかを見てみましょう。JavaScript オブジェクト ( virtual ) を再作成し、古いものと新しい virtual を比較し、変更された要素を見つけて更新する必要があります。もう 1 つの要因は、ページのコード サイズに関係します。たとえば、ページ サイズが大きくなると、更新時のパフォーマンスの消費も大きくなります。仮想では変更部分を更新する必要がありますが、これは更新する必要があるデータの量に関連しており、ページ サイズとは関係ありません。したがって、ページが大きくなるほどパフォーマンスの消費も大きくなり、仮想パフォーマンスの消費をはるかに超えるという結論になります。DOM
DOM
DOM
DOM
DOM
innerHTML
DOM
innerHTML
DOM
操作方法 | JSレベル | DOM レベル |
---|---|---|
ネイティブJS | 純粋な JS 操作 | DOM 手術 |
innerHTML |
Pure JS 操作の HTML 文字列DOM 解析 |
破棄DOM +DOM 作成 (ページ サイズに関連) |
バーチャルDOM |
仮想DOM +Diff アルゴリズムを作成する |
変更部分の更新はDOM 更新データ量に関係します |
DOM
上記の分析とパフォーマンス消費量の比較によれば、ネイティブ JS < 仮想<であることがわかりますinnerHTML
。この場合、なぜネイティブ JS を使用しないのでしょうか? これにより、別の重要な疑問が生じます可维护性
。
保守性
ネイティブ JS の操作が最もパフォーマンスが優れていますが、実際のビジネス プロジェクト開発では、ネイティブ JS を直接使用して開発することはほとんどなく、以前はネイティブ JS を使用していましたが、現在は 、 、などを使用してJQuery
いAngular
ます。これは主に、開発者の精神的負担が軽減され、迅速な開発とコードのメンテナンスが容易になるためです。Vue
React
命令的
ネイティブ 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
。もちろん、レスポンシブなどもあるので、これは使用理由の一部にすぎません。