vuejs は仮想 DOM ですか?

青灯夜游
青灯夜游オリジナル
2021-09-06 17:07:033159ブラウズ

vuejs は仮想 DOM であり、Vue.js2.0 では Virtual DOM (仮想 DOM) メカニズムが導入され、初期レンダリング速度が 2 ~ 4 倍向上し、メモリ消費量が大幅に削減されました。仮想 DOM の利点: クロスプラットフォーム、効率の向上、レンダリング パフォーマンスの向上などが可能です。

vuejs は仮想 DOM ですか?

このチュートリアルの動作環境: Windows7 システム、vue2.9.6 バージョン、DELL G3 コンピューター。

Vue.js 2.0 では Virtual DOM が導入されており、Vue.js 1.0 の初期レンダリング速度よりも 2 ~ 4 倍高速になり、メモリ消費量が大幅に削減されます。では、仮想 DOM とは何でしょうか?なぜ仮想 DOM が必要なのでしょうか?ページのレンダリング効率はどのように向上しますか?これがこの記事で検討する問題です。

テンプレートをビューに変換するプロセス

Virtual Dom を正式に導入する前に、まずテンプレートをビューに変換するプロセス全体を理解する必要があります (

  • Vue.jsはコンパイルによりテンプレートを描画関数(render)に変換し、その描画関数を実行することで仮想ノードツリーを取得できます。モデルを操作すると、対応する Dep の Watcher オブジェクトがトリガーされます。 Watcher オブジェクトは、対応する update メソッドを呼び出してビューを変更します。このプロセスでは主に、新旧の仮想ノードの違いを比較し、比較結果に基づいて DOM 操作を実行してビューを更新します。
  • 簡単に言うと、Vue の基盤となる実装では、Vue はテンプレートを仮想 DOM レンダリング関数にコンパイルします。 Vue 独自の応答システムと組み合わせることで、状態が変化したときに、Vue はコンポーネントの再レンダリングの最小コストをインテリジェントに計算し、DOM 操作に適用できます。

まず、上の図の概念を説明しましょう:

  • レンダリング関数

    : レンダリング関数は次のとおりです。仮想 DOM を生成するために使用されます。 Vue では、アプリケーション インターフェイスを構築するためにテンプレートを使用することをお勧めします。基盤となる実装では、Vue はテンプレートをレンダリング関数にコンパイルします。もちろん、より適切な制御を得るために、テンプレートを作成せずにレンダリング関数を直接記述することもできます。

  • VNode 仮想ノード

    : 実際の dom ノードを表すことができます。 VNode は、createElement メソッドを通じて dom ノードにレンダリングできます。簡単に言えば、vnode は実際の DOM ノードの作成方法を記述する node description object として理解できます。

  • patch (パッチアルゴリズムとも呼ばれます)

    : 仮想 DOM のコア部分であり、vnode を実際の DOM にレンダリングできます。このプロセスは、新旧を比較することです。それらの違いは何か、比較結果に基づいて更新が必要なノードを見つけて更新します。これは言葉の意味からもわかりますが、パッチ自体はパッチまたは修復を意味し、実際の機能は既存の DOM を変更してビューを更新することです。 Vue の仮想 DOM パッチ適用アルゴリズムは Snabbdom の実装に基づいており、これらの基盤に基づいて多くの調整と改善が行われています。

仮想 DOM とは何ですか?

仮想 DOM は実際には JavaScript オブジェクト (VNode ノード) に基づいたツリーです。オブジェクト属性はノードを記述するために使用されます。実際、それは実際の DOM を抽象化したレイヤーにすぎません。最後に、一連の操作を通じて、このツリーを実際の環境にマッピングできます。

簡単に言うと、Virtual DOM は単純な JS オブジェクトとして理解でき、少なくとも 3 つの属性 (タグ名 (tag)、属性 (attrs)、子要素オブジェクト (children)) が含まれています。フレームワークが異なると、これら 3 つのプロパティの名前が若干異なります。

仮想 DOM については、次の図に示すような簡単な例を見てみましょう。

テンプレート → レンダリング関数 → 仮想 DOM ツリー → 実際の DOM

## というプロセスを詳しく説明します。

#仮想 DOM の役割は何ですか?

仮想 DOM の最終的な目標は、仮想ノードをビューにレンダリングすることです。ただし、仮想ノードを直接使用して古いノードを上書きすると、不要な DOM 操作が多数発生します。たとえば、ul タグの下に多くの li タグがあり、変更された li は 1 つだけである場合、新しい ul を使用して古い ul を置き換えると、これらの不必要な DOM 操作によりパフォーマンスの無駄が発生します。

不要な DOM 操作を回避するために、仮想ノードをビューにマッピングするプロセス中に、仮想 DOM は仮想ノードを、ビューの最後のレンダリングで使用された古い仮想ノード (oldVnode) と比較して、更新されたノードは DOM 操作の実行に使用されるため、変更する必要のない他の DOM に対する操作が回避されます。 実際、仮想 DOM は Vue.js で主に 2 つのことを行います。

実際の DOM ノードに対応する仮想ノード vnode を提供する

仮想ノード vnode を変換する古い仮想ノード oldVnode と比較し、ビューを更新します。
  • なぜ仮想 DOM が必要なのでしょうか?

クロスプラットフォームの利点がある

    仮想 DOM は JavaScript オブジェクトに基づいており、実際のプラットフォーム環境に依存しないため、クロスプラットフォームの利点があります。ブラウザ プラットフォーム、Weex、Node などの機能。
    • 操作 DOM は遅いですが、js は効率的に実行されます。 DOM 比較操作を JS レイヤーに配置して効率を向上させることができます。

    DOM 操作の実行速度は Javascript よりもはるかに遅いため、多くの DOM 操作が Javascript に移行され、パッチ適用アルゴリズムを使用して実際に必要なノードを計算します。更新され、Reduce DOM 操作が最大化され、パフォーマンスが大幅に向上します。

    仮想 DOM は基本的に、JS と DOM の間にキャッシュを作成します。 CPU とハードディスクに例えると、ハードディスクは遅いのでその間にキャッシュを追加し、DOM は遅いので JS と DOM の間にキャッシュを追加します。 CPU (JS) はメモリ (仮想 DOM) のみを操作し、最終的に変更をハードディスク (DOM) に書き込みます

    • レンダリング パフォーマンスの向上

    の利点仮想 DOM は単一の操作ではなく、大規模で頻繁なデータ更新のコンテキストで、ビューを合理的かつ効率的に更新できます。

    効率的な DOM 操作を実現するには、効率的な仮想 DOM diff アルゴリズムが必要です。 今回はパッチの核となる diff アルゴリズムを使用して、DOM 内で更新が必要なノードを見つけて更新し、他のノードは更新しません。たとえば、モデルを 100 回変更して 1 から 100 に増やした場合、Virtual DOM のキャッシュを使用すると、最後の変更のみがビューにパッチされます。 diff アルゴリズムの実装プロセスはどのようなものですか?

    diff アルゴリズム

    Vue の差分アルゴリズムは、snabbdom に基づいて変更されます。同じレベルの vnode 間でのみ diff を実行します。 、同じレベルの vnode の差分を再帰的に実行し、最後に DOM ツリー全体を更新します。クロスレベル操作は非常に少なく無視できるため、時間計算量は O(n3) から O(n) に変化します。

    diff アルゴリズムにはいくつかのステップが含まれています:

      JavaScript オブジェクト構造を使用して DOM ツリーの構造を表し、このツリーを使用して実際の DOM ツリーを構築し、それをdocument
    • 状態が変化すると、新しいオブジェクト ツリーを再構築します。次に、新しいツリーと古いツリーを比較し、2 つのツリー間の相違点を記録します。
    • 記録された相違点を構築された実際の DOM ツリーに適用すると、ビューが更新されます

    diff アルゴリズムの実装プロセス

    diff アルゴリズム自体は非常に複雑で実装が困難です。この記事では複雑さを単純化し、次の 2 つのコア関数の実装プロセスを簡単に紹介します。

      patch(container,vnode): 初期レンダリング中に、VDOM は実際の DOM にレンダリングされてから、容器。
    • patch(vnode,newVnode): 再度レンダリングするときに、新しい vnode と古い vnode を比較し、その差分を構築された実際の DOM ツリーに適用します。

    1. patch(container,vnode)

    この関数を通じて、VNode を実際の DOM にレンダリングできます。次のシミュレーション コードを通じて、次のことができます。一般的なプロセスを理解します:

    function createElement(vnode) {    
    var tag = vnode.tag  
    var attrs = vnode.attrs || {}    
    var children = vnode.children || []    
    if (!tag) {       
     return null  
      }    
    // 创建真实的 DOM 元素    
    var elem = document.createElement(tag)   
     // 属性    
    var attrName    
    for (attrName in attrs) {    
        if (attrs.hasOwnProperty(attrName)) { 
               // 给 elem 添加属性
               elem.setAttribute(attrName, attrs[attrName])
            }
        }
        // 子元素
        children.forEach(function (childVnode) {
            // 给 elem 添加子元素,如果还有子节点,则递归的生成子节点。
            elem.appendChild(createElement(childVnode))  // 递归
        })    // 返回真实的 DOM 元素   
     return elem
    }

    2. patch(vnode,newVnode)

    ここでは、vnode と newVnode の比較のみを考慮します:

    function updateChildren(vnode, newVnode) {
        var children = vnode.children || []
        var newChildren = newVnode.children || []
      // 遍历现有的children
        children.forEach(function (childVnode, index) {
            var newChildVnode = newChildren[index]
      // 两者tag一样
            if (childVnode.tag === newChildVnode.tag) {
                // 深层次对比,递归
                updateChildren(childVnode, newChildVnode)
            } else { 
      // 两者tag不一样
               replaceNode(childVnode, newChildVnode) 
           }
        }
    )}
    関連推奨事項 :《

    vue.js チュートリアル

以上がvuejs は仮想 DOM ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。