🌲

DOMと仮想DOMについて

に公開

初めに

こんにちは!DOM仮想DOMの違いについてまとめていきたいと思います。

DOM(Document Object Model)とは?

簡単にまとめると、以下のようになります。

  • DOMは、HTMLやXML文書をオブジェクトとして扱うための仕組み。
  • JavaScriptなどのプログラミング言語から、Webページの構造や内容を 動的に操作可能。
  • ブラウザがHTMLを読み込むと、ツリー状の構造(DOMツリー) として内部的に保持する。

DOMの構造(DOMツリー)

以下のHTMLを例に DOMの構造(DOMツリー) について説明していきたいと思います。

<!DOCTYPE html>
<html>
  <head>
    <title>サンプルページ</title>
  </head>
  <body>
    <h1>Hello</h1>
    <p>World</p>
  </body>
</html>

これがDOMツリーとして解釈されると以下のように、各要素が「ノード(Node)」として扱われ、それぞれ親子関係を持ちます。JavaScriptからこのツリー構造を使って、ページを操作・変更できます。

DOMの操作

基本的ななDOMの操作についてまとめていきたいと思います。

  1. 要素の取得

    const heading = document.querySelector("h1");
    const paragraph = document.querySelector("p");
    
    • document.querySelector():CSSセレクタで最初に一致する要素を取得
  2. テキストを変更する

    heading.textContent = "こんにちは";
    paragraph.textContent = "世界";
    
    • textContent:中のテキストを変更できるプロパティ
  3. 新しい要素を追加する

    const newDiv = document.createElement("div");
    newDiv.textContent = "新しい要素です";
    document.body.appendChild(newDiv);
    
    • createElement():新しい要素ノードを作成
    • appendChild():既存のノードに子要素として追加
  4. 要素を削除する

    paragraph.remove(); // <p>World</p> を削除
    

    もしくは、

    const p = document.querySelector("p");
    p.parentNode.removeChild(p);
    
  5. イベントを追加する

    heading.addEventListener("click", () => {
    alert("h1がクリックされました!");
    });
    
    • addEventListener()でユーザーの操作(クリック・入力など)に反応

DOM操作におけるパフォーマンスの課題

  1. DOMの再描画(Repaint)・再レイアウト(Reflow)が重い
    • DOMを変更すると、ブラウザは画面を更新するために「再描画」や「再レイアウト」を行います。
    • この処理が頻繁すぎると処理が重くなるため、アニメーションやスクロール時にカクついたりします。
  2. 大量のDOMノードがあるとレンダリングが遅くなる
    • 要素数が多くなると、レンダリングにかかるコストが上がる。
    • 特にテーブルリストスプレッドシートのような構造で顕著。

仮想DOMとは?

仮想DOMとは、本物のDOMを直接操作する代わりに、JavaScriptで仮のDOMツリーを作って、それを使って効率的に更新を行う仕組みです。

仮想DOMの仕組み

  1. 状態の変更
    • 例えば、ユーザーがボタンをクリックして、ReactのuseStateで値が更新される。
  2. 新しい仮想DOMツリーの構築
    • 状態の変化に応じて、Reactなどが新しい仮想DOMを生成する。
  3. 差分検出
    • 以前の仮想DOMと新しい仮想DOMを比較して、変更された部分(差分)だけを検出する。
  4. パッチ
    • 検出した差分だけ、本物のDOMに適用する。

まとめ

DOMは、HTMLやXML文書をオブジェクトとして扱うための仕組みです。
仮想DOMは、実際のDOMの状態をJavaScript上で仮想的に再現したツリー構造です。
仮想DOMは差分検出を行い、本物のDOMへの最小限の更新のみを実施して描画効率を高めます。

Discussion