仮想DOMって何？って疑問を5分で解決する

## はじめに

**VueやReactで開発しているけれど、仮想DOMって何？**

数分前の僕は仮想DOMというか、DOMの言葉の意味もなんとなくしかわかってませんでした。

ただ、仮想DOMについて調べるうちに「なるほど！そういうことか」と理解できたので5分でわかるように解説してみます。

### この記事でわかること
この記事を読み終えたあなたは
- DOM、仮想DOMの意味と違いを説明できる
- ReactやVueがどうやって動いてるかわかる

と、もうDOMがわからない状態を卒業できるはずです。

また、仮想DOMって「知ってたらインテリっぽい」雑学感ありますが学んでみるとメリット多かったです。

DOMの仕組みを知ってると、

- パフォーマンスの良いコードを書ける
- 良い・悪いコードの区別がつく
- レンダリングでバグになった時に、内部構造がわかり対処しやすい

などなど、普通に使えます。

### 対象読者
この記事は、以下の読者を想定してます↓
- ReactやVueなどフロントエンド開発をしてる人
- DOMについて調べたけど、いまいちわからなかった人

ただ、初心者の方でもわかるように噛み砕いてるのですらすら読めるはずです。

## そもそも、DOMって何？
仮想DOMを知る前に、「DOMって何？」って状態の人もいるはずなので解説します。
(仮想DOMを理解する上で必要になる知識なので、焦らずに行きましょう。)

### DOMはWebページの「設計図」
DOMの正式名称は「Document Object Model（ドキュメント・オブジェクト・モデル）」と言い、3つの要素で成り立ってます。

**Document（ドキュメント）**
一言で言えば「Webページそのもの」を指します。
今あなたが読んでいるこのブログ記事ページも、ひとつの「ドキュメント」です。

例えば、以下のような僕のプロフィールページもドキュメントです↓

![スクリーンショット 2024-12-20 21.13.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577619/9bb0031e-df08-8ece-33fb-10b3c898951c.png)

**Object（オブジェクト）**
Webページには
- テキスト(文字)
- 画像
- ボタン
- 広告
- フォーム

など、さまざまな要素があります。
これら1つひとつをプログラム上で扱いやすくした「モノ（要素）」がオブジェクトです。

[![Image from Gyazo](https://i.gyazo.com/011efa5ab7ff413e516ab8197531d417.png)](https://gyazo.com/011efa5ab7ff413e516ab8197531d417)

**Model（モデル）**
モデルとはこれらのオブジェクトがWebページ上でどこに、どんなふうに並んでいるかをツリー構造（親子関係）で表した設計図のようなものです。

オブジェクトはこれとすると
![スクリーンショット 2024-12-20 21.26.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577619/f17b8563-928c-7b0f-ae8f-c644ea83a3c1.png)
モデルは下記になる↓
![スクリーンショット 2024-12-20 21.27.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577619/daa4e2c2-d28a-723f-2404-5e156e14e838.png)


このモデルこそがDOMで、DOMとは「Webページのオブジェクトの位置関係を表した設計図」と言えます。

### DOMの情報はどこに保存されているのか？
ここまで解説したのですが、DOMってどこに保存されてるの？って思ってる人もいるはず。(少なくとも僕は思いました)

DOMはブラウザのメモリ上に(一時的に)保存されています。
(メモリとは、コンピュータ内の記憶装置です。ロッカーのように小さな物を格納できるイメージです。)

DOMとHTMLファイルを混合しがちなので分けると
- HTMLファイル：サーバーに保存されてる
- DOM：ブラウザのメモリ

って違いがあります。

また、DOMツリーはあくまでブラウザ起動中（ページ表示中）だけメモリ上に存在する一時的なデータです。
なので、ページを閉じればメモリ上のDOMツリーは消え、再度ページを開けば新たに構築されます。

### ブラウザはDOMをどう処理しているの？
ところで、ブラウザはDOMをどういった流れで処理しているのでしょうか？
ここを知ることで、仮想DOMとの違いがよりわかりやすくなります。

DOMを処理する流れは
1. HTMLファイルをサーバーからダウンロード
2. HTML文書を解析(`p`タグなどを見つけてく) 
3. DOMツリーを構築[(これ)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577619/daa4e2c2-d28a-723f-2404-5e156e14e838.png)
4. CSSの適用
4. Webページを表示（レンダリング）

です(図解↓)
![napkin-selection (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577619/cb6320df-fc0b-1f1e-ed95-b3cfad967a0f.png)


DOMツリーをもとにCSSで装飾するため、Webページに欠かせないのがDOMってわけです。
### DOMの問題点
ただ、これまで解説してきたDOMには問題点があります。
それは、**「DOMを更新するときに広い範囲を再計算する」** 必要があることです。

小規模な更新なら問題ありませんが、大規模アプリになると変更が起こるたびにブラウザは多くの要素を再計算します。

その結果、画面がカクついたり、操作が重くなったりする原因になります。

この画面がカクつく問題を解決するために生まれたのが「仮想DOM」です。
お待たせしました。ここから仮想DOMについて解説します。

## 仮想DOMって何？
先ほど伝えた通り、DOMを直接何度も更新するとパフォーマンスが悪くなる問題がありました。

ここで登場するのが仮想DOMです。  
仮想DOMとは実際に表示されるものではなく、あくまでもメモリ上で扱う **「DOMのコピー」** です。

「え？コピーなんて作って何の役に立つの？」って思った人もいるはずです。

簡単に説明するとDOMに更新があった時に
1. コピーのDOM(仮想DOM)を更新する
1. 変更があった箇所だけを検知
1. 変更箇所だけを、DOMに反映

するため、更新する要素が少ないのです。

これによって、更新が「軽く」なるためカクつきや画面が重くならないって仕組みです。
### 仮想DOMでWebページを表示する仕組み
具体的に、仮想DOMでWebページを表示する方法は
1. HTMLファイルの読み込み
1. メモリ上での仮想DOMを作成
1. リアルなDOMを作成→表示する

で、一旦Webページを表示(レンダリング)します。

その後、Webページに変更があった場合
(例：ボタンを押したら文言を変えるなど)
1. 変更内容を仮想DOMで計算  
3. 差分を抽出し、必要最低限の箇所だけDOMを更新

図解↓
![napkin-selection (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577619/1a71790a-57e4-034e-7d20-b8876faa63c6.png)

変更があった箇所だけ更新していくので、軽い動作でカクつかないわけです。
(イメージ的には、Gitのマージみたいな感じです！)

### 仮想DOMが使われてるフレームワーク
以下の2つが有名で、仮想DOMが広がったきっかけでもあるフレームワークです↓
- React
- Vue.js

その他のフレームワークでも仮想DOM使われており、今やモダンなフロントエンド開発の基礎知識として知っておいて損はないですね。

(フロントエンドをこれから学ぶ人は上記の言語から始めるのがおすすめですよ！)
## 仮想DOMの歴史
最後に、「仮想DOMっていつからある技術なの？」と思って歴史を調べてたら、割と面白かったので記事にしました。

ここでは、Webが静的ページ中心だった時代から、仮想DOMが主流となるまでの歴史をざっくりと振り返りますね。

### 2000年代〜2010年代前半 「jQuery全盛の時代」

2000年代から2010年代前半にかけてのWebは、今ほど複雑なインタラクションを必要としていませんでした。

当時は多くのページが静的なコンテンツを表示するだけで、ユーザーがボタンを押せば少し画面が変わる程度。

大規模なシングルページアプリケーション（SPA）やリアルタイムなUI更新は、まだそれほど一般的ではありません。
 
2010年前半までDOMをいじりたい場合、jQueryを使って
```javascript: jQueryのコード
$('#element').text('テキスト変更')
```
のように直接リアルDOMを変更する手法が当たり前でした。

ただ、小規模なページ更新であれば問題ありませんが、Webアプリが複雑になるにつれ、表示がカクつく・操作が重くなるなどのパフォーマンス問題が顕著になってきました。

**「このままでは、もっと複雑なWebアプリは作りにくいな…」** そんな悩みがフロントエンド開発者たちの間に広がり始めた時代です。

### 2013年頃 「Reactの登場と仮想DOMの注目」
2013年、Facebook（現Meta）が「React」というJavaScriptライブラリを公開しました。このReactこそ、仮想DOMを一般に広めた大きなきっかけとなった存在です。

Reactは以下2つの革命をフロントエンド開発に起こしました↓
- 仮想DOMの採用
- UIをデータから自動で計算する

(え？ReactってFacebookが開発したんだ！)
### 2014年〜2015年以降 「Vue.jsなど他フレームワークへ波及」
2014年にリリースされた**Vue.js**も、Reactと同様に仮想DOMを取り入れたシンプルな仕組みで注目を浴びます。

Vueでは`data`が変化すれば、テンプレートから自動的に新しい仮想DOMが生成され、必要最小限の更新がリアルDOMに反映されます。

この頃から「高性能なUI描画＝仮想DOM」という認識が広く共有されるようになりました。

### 2016年以降 「さらなる最適化や新手法の登場」

2016年以降、仮想DOMは多くのフレームワークで標準装備となり、開発者はDOM操作の煩雑さから大幅に解放されました。

しかし、テクノロジーは常に進化します。2020年代に入ると、仮想DOMなしでも高速な更新が可能なフレームワークや仕組みが登場し始めてるようです。

(え？もう仮想DOMより高速な更新ってもうあるの？)

例えば、以下のような技術があります↓
- **Svelte**：コンパイル時に必要なコードだけを生成し、仮想DOMを使わずに高速なUI更新をする
- **SolidJS**：シグナル（リアクティブな変数）を活用して必要最小限の部分だけ更新する

これらの新しいアプローチは、仮想DOMを使わなくても十分なパフォーマンスが得られることを示しています。

### 現在（2024年時点）の状況
2024年現在でも、ReactやVueなどの仮想DOMを基盤としたレンダリングが主流です。
また、これらのフレームワークはエコシステムやドキュメント、コミュニティの充実もあり、依然として人気があります。

ただ、新しい技術も出始めてフロントエンド開発はますます進化しそうです。今後のテクノロジーの進化も楽しみですね！

## おわりに
簡単にこれまでの内容をまとめました↓
- そもそも、DOMとは何か？
  - 「Webページを要素ごとに分解し、ツリー構造で表した設計図のようなもの」
- 仮想DOMとは何か？
  - リアルDOMの仮想的なコピーをメモリ上に持ち、変更点だけを抽出して最小限の更新を行う仕組み
- 仮想DOMの歴史
  - 2000年代〜2010年代前半：直接DOM操作の時代
  - 2013年：React登場による
  - 2014年以降：仮想DOM普及その後のVue採用
  - 2024年現在(執筆時点)：現在でも主流のレンダリング方法

といった流れで解説してきました。  

これらを理解することで、VueやReactがなぜ「仮想DOM」を採用しているのか、そのメリットや背景が、より明確にイメージできるはずです。

もし、この記事を読んで疑問やわかりづらい点がありましたら、ぜひお気軽にコメントしてください。  
「この部分がよくわからない」「ここをもっと詳しく知りたい」というリクエストも大歓迎です。

この記事をきっかけに仮想DOMのことが理解できる人が増えたら嬉しいです。
それでは！