LoginSignup
1
4

More than 3 years have passed since last update.

【Vue.js】仮想DOMについてまとめてみた

Posted at

はじめに

Vue.jsを学習していく中で「仮想DOM」という概念を知りました。
そもそも仮想DOMとは何なのか、どんなメリットがあるのか調べたのでまとめてみました。

そもそもDOMって何?

DOMとはDocument Object Modelの略で、HTMLやXML文書を操作するためのAPI(インターフェイス)です。
ウェブページとJavaScriptなどのスクリプト言語を繋ぐ橋渡し的な存在です。

仮想DOMと区別するためにリアルDOMと呼ぶこともあります。

DOMツリーって何?

DOMのモデルは文書をツリー構造で表現します。
<html>タグから枝分かれしていき、<head>,<body>タグ、その中身のタグや要素に分かれていきます。

viertual_dom.png

このDOMツリーの<html>,<body>といった一つ一つの要素をオブジェクトとして扱い、これらをNode(ノード)と呼びます。

仮想DOMの発想の原点

ウェーブページの内容はDOMに格納されていて、内容を変更したいときにJavaScriptなどの言語を介して操作することができます。
DOM操作の処理フローは以下のようになっています。

  1. DOMツリーを再構築する
  2. DOMツリーとCSSOMツリー※を組み合わせてレンダリングツリーを構築する
  3. レンダリングツリーでレイアウトを行い、各ノードの位置やスタイルを計算する
  4. レイアウト結果をもとに描画する

※ CSSOM: CSS Object Modelの略で、CSS版DOMのようなものです。

レンダリングはブラウザにとってコストの高い処理となるため、できるだけ避けたいフローです。無駄なレンダリングをなくし、効率の良い処理をするためにはどうすれば良いでしょうか。

変更があった部分のみレンダリングする

これが実現できれば無駄なレンダリングは起きませんよね。
そこで考えられたのが、仮想DOMという概念です。

仮想DOMって何?

簡単にいうと、リアルDOMを模したJavaScriptのオブジェクトです。

  1. 仮想DOMを2種類用意する
  2. 一方の仮想DOMをJavascriptで操作
  3. 変更前後の仮想DOMの差分を比較
  4. 差分だけをリアルDOMに反映

スクリーンショット 2021-04-01 15.40.27.png

上記のようなフローでリアルDOMを操作します。
仮想DOMを用いることで、無駄なレンダリングを避ける以外に

  • ロジックとUIが分離できる
  • 状態の管理を簡単にできる
  • ロジックとUIを繋ぐ処理を簡単にできる

といったメリットがあります。

リアルDOMと仮想DOMを比べてみよう

ここからは実際にリアルDOMと仮想DOMの処理の違いを見ていきたいと思います。

  • 素のJavaScript(リアルDOM)を使う場合
  • Vue.js(仮想DOM)を使う場合

今回は簡単なカウントアップ処理で2つを比べていきます。

リアルDOM(JavaScript)

index.html
<div id="app">
  <button class="count_up">count up</button>
  <p class="count_num">0</p>
</div>
app.js
const countButton = document.querySelector('.count_up');
const state = { count: 0 };

countButton.addEventListener('click', () => {
    const countContent = document.querySelector('.count_num');
    countContent.innerHTML = ++state.count;
});

上記のようなリアルDOMの操作は

  • ボタンをクリックするとp.count_numが書き変わるというUIと、カウントをインクリメントするというロジックが混同している
  • UIとロジックを繋ぐaddEventListenerを使っている。(より複雑になるとaddEventListenerが増えがち)

などのデメリットがあります。

仮想DOM(Vue.js)

index.html
<div id="app">
   <button @click="countUp">count up</button>
   <p>{{ count }}</p>
</div>
app.js
new Vue({
    el: "#app",
    data: {
        count: 0,
    },
    methods: {
        countUp: function() {
            this.count += 1;
        }
    }
})

リアルDOMの操作に比べると

  • UIとロジックが分離できる
  • @clickを使うことでUIとロジックを繋ぐ処理が簡単になった
  • 状態の一元管理ができる

といったメリットがあります。

まとめ

仮想DOMはレンダリングコストの削減だけでなく、UI/ロジックの分離や状態管理の簡略化など、開発の効率を上げる上で必須の概念であると理解しました。

参考文献

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4