🗣️

DOMの操作と仮想DOMを比較

2023/07/01に公開

普通のDOMと仮想DOMでコードを比較してみた

Github Copilotに助けてもらいながら、苦手なDOMの操作をするコードを書いてみました。仕事では、Pythonしか使ったことないので、JavaScriptはUdemyで勉強してました。htmlとcssも仕事では、あんまり書いたことないです💦
画面は、Dashってフレームワークで作ってましたね。

DOMとは?

DOMとは、Document Object Modelの略で、HTMLやXMLのようなドキュメントをプログラミング言語で操作するための仕組みのこと

生のJavaScriptだと、idやクラスを指定して、DOMを操作して画面に動きをつけます。APIからデータを取得して、ulタグの中に、liタグを新たに作り出し、forEachでループして、配列の数だけ要素を作り出します。
これだと、複雑になっちゃいますね。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <ul class="api">
  </ul>
  <script>
    // DOMを操作して、apiクラスに対してfetchJsonPlaceholderDataの値を画面に描画する
    const api = document.querySelector('.api');
    const fetchJsonPlaceholderData = async () => {
      try {
        const response = await fetch('https://jsonplaceholder.typicode.com/posts');
        const data = await response.json();
        console.log(data);
        data.forEach((item) => {
          const li = document.createElement('li');
          li.textContent = item.title;
          api.appendChild(li);
        });
      } catch (error) {
        console.error('Error fetching data:', error);
      }
    }

fetchJsonPlaceholderData();
  </script>
</body>
</html>

仮想DOMとは?

仮想DOMとは、ブラウザ上に表示されているDOMとは別に、メモリ上に仮想的にDOMを作成し、その差分を検知して、ブラウザ上のDOMを更新する仕組み

仮想DOMを使えば、DOMの操作をせずに、決まったコードを記述するだけで、APIから取得したデータを画面に描画することができます。
useStateに、useEffectで実行したメソッドから取得したAPIのデータを保持させて、htmlの中に、JavaScriptのmapメソッドを使って、配列のデータを表示しています。

import { useState, useEffect } from "react";

function App() {
  // データの型を定義するinterfaceを作成
  interface Data {
    id: number;
    name: string;
  }

  // Data型の配列を作成
  const [data, setData] = useState<Data[]>([]);
  // JSONPlaceholderからデータを取得する関数
  const getData = async () => {
    // JSONPlaceholderからデータを取得
    const response = await fetch("https://jsonplaceholder.typicode.com/users");
    // 取得したデータをJSON形式に変換
    const data = await response.json();
    // 変換したデータを変数に格納
    setData(data);
  };
  // コンポーネントがマウントされた時に実行する関数
  // マウントとは、コンポーネントがDOMに追加されること
  // アンマウントは、コンポーネントがDOMから削除されること
  useEffect(() => {
    getData();
  }, []);// []は第二引数で、空の配列を渡すことで、コンポーネントがマウントされた時のみ実行されるようになる
  // 取得したデータを表示する

  return (
    <>
      <ul>
        {data.map((item) => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </>
  );
}

export default App;

まとめ

比較したコードが、そんなに多くないので変わらないなと思いますが、フレームワークやライブラリーを使えば、短いコードやnpmのパッケージを使用して、Webアプリケーションを開発することができます。

それと、Sierで働いていたときに聞いたのですが、普通のhtmlだと画面がチラつくから、最近の開発では仮想DOMを使うのだとか?

👀なぜ仮想DOMを使うのか?

AIに聞きました!

仮想DOM(Virtual DOM)は、JavaScriptフレームワークやライブラリ(例:React、Vue.js)で使用される一般的なアプローチです。仮想DOMの使用は、効率的なDOM操作とパフォーマンスの向上を実現するために導入されました。

通常のHTMLでは、ページの要素を変更するたびにブラウザはリアルなDOMを直接操作します。この場合、要素の追加、削除、属性の変更などが直接反映されます。一方、仮想DOMでは、変更を即座にリアルなDOMに反映する代わりに、仮想のメモリ上の表現(Virtual DOM)を使用します。

仮想DOMでは、以下のような手順で変更を処理します:

  1. JavaScriptコードで仮想DOMを更新します。
  2. 仮想DOMとリアルなDOMの差分を比較します。
  3. 差分のみをリアルなDOMに反映します。

この手順により、全体のDOMを再描画する必要がなくなり、ブラウザによる実際のDOM操作が最小限に抑えられます。その結果、画面のチラつきを最小限に抑えることができます。

一方、通常のHTMLでは、直接DOMを操作するため、要素の変更が即座に反映されます。このため、動的な変更が行われる場合、ブラウザは部分的な再描画を行い、その結果、チラつきが生じる可能性があります。

要約すると、仮想DOMは変更の差分を最小限に抑え、効率的なDOM操作を実現するため、通常のHTMLに比べてチラつきを軽減することができます。

Discussion