DOMって結局なに? HTMLテキストが「動かせる画面」に変わる仕組み

DOMって何?
DOMという言葉を聞いたことはあるだろうか?
ウェブ開発業界に身を置いている者であれば、HTMLを勉強しているという者であれば、知っているべき技術的要素である。サイトの動作を軽くすることを追求し、突き詰めようとした時、どうしてもこのDOMについて理解していることが求められるからだ。
そんな実は重要な技術 DOMに関して、分かりやすい良い感じの一言説明を探していたが、ウィキペディアの説明が簡潔で分かりやすかったので引用させていただきたい。
マークアップがなされたリソース(Document)をリソース要素(Object)の木構造(Model)で表現し操作可能にする仕組み、またそのモデルである。
こちらの説明の良いところは、DOMがDocument Object Modelの略であるということも一緒に説明されているということだ。そしてさらに、ここから行うDOMが作られる流れの説明と直結した説明になっていることも非常に有りがたい。
そもそもDOMがウェブ開発において、どうして重要なのか?
皆さんが見ているウェブサイトは、ブラウザを通じて皆さんに届けられている。ブラウザはURLで指定されたサーバーからデータをもらってきて、それを良い感じにレンダリング(描画)してくれる。このレンダリングの処理の過程で「HTMLをDOMにする」という制御が入ってくるのだ。
HTMLからDOMへ
HTMLがHyperText Markup Languageの略であるということからも分かる通り、HTMLはマークアップ言語である。要は「マークアップがなされたリソース(Document)」だ。そんなHTMLの中身には、サイトを構成する要素が、タグという形で木構造に整理されている。
例えば。下記は「Hello, World!」だけを表示するHTMLである。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World with Button</title>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
上記のHTMLは下記のような木構造で表現することが可能だ。
html (ルート要素)
│
├── head (ヘッダー情報)
│ ├── meta (文字コード設定: UTF-8)
│ ├── meta (ビューポート設定)
│ └── title (ページタイトル)
│ └── "Hello World with Button" (テキスト)
│
└── body (画面に表示される本体)
└── h1 (見出し)
└── "Hello, World!" (テキスト)
そもそもHTMLで書かれた内容は、<head>という親に<meta>や<title>というような子要素がぶら下がっているというように、いわばサイトの枠組みを表現した設計書のようなものである。しかしブラウザにとって、テキストベースの設計書のままでは、「どこをどう画面に描画するのか」「クリックイベントをどう制御すればいいのか」といったことを制御するのは難しい。
そこでブラウザは、このテキストの設計書を読み込み、メモリ上に「ノード」と呼ばれるオブジェクトの木構造として展開する。この「ブラウザが操作・描画しやすいようにプログラム上のオブジェクトとして組み立て直したデータ構造」こそが、DOM(Document Object Model)なのである。
なぜDOMが必要なのか?
テキストベースの設計書のままでは制御するのは難しいと、先ほど言及した。しかし、それは何故だろうか? HTMLで記載した内容はそもそもが木構造になっており、DOMもまた、「ノード」と呼ばれるオブジェクトの木構造として展開しているらしい。
わざわざDOMというオブジェクト構造にする最大の理由は、「JavaScriptからWebページを動的に変更・操作できるようにするため」だ。
例えば、ユーザーがボタンを押した時に見出しのテキストを書き換えたいとする。もしDOMが存在せずただのテキスト(HTML)のままであれば、ページ全体をリロードしてサーバーから新しいHTMLを読み直すしかない。
しかし、ブラウザがHTMLをDOM(オブジェクトのツリー構造)として管理してくれていれば、JavaScriptを使ってツリーの特定のノード(要素)だけをピンポイントで書き換えることができる。
// JavaScriptでDOMノード(h1タグ)を取得してテキストを書き換える例
const heading = document.querySelector('h1');
heading.textContent = 'こんにちは、世界!';
上記のように document.querySelector('h1') と指定できるのは、ブラウザ内部でHTMLが document オブジェクトを頂点としたDOMツリーとして構築されているからに他ならない。
補足:実際のブラウザの裏側について
実際のブラウザ内部では、HTMLからDOMを作るだけでなく、CSSを解析して「CSSOM」を作ったり、それらを合体させて画面描画用の「レンダーツリー」を構築したりと、もっと複雑な処理を行っています。ただ、まずは「HTMLという文字データを、JavaScriptから触れるオブジェクト構造(DOM)に変換している」という基本イメージを理解しておくことが大事かと思います。
まとめ
- Document(文書): HTMLファイル(テキスト形式の設計書)
- Object(要素): JavaScriptなどで操作できるプログラム上のオブジェクト
- Model(構造): それらが階層状(木構造)に組み合わさったモデル
DOMとは、一言で言えば「ブラウザがHTMLテキストを解釈し、JavaScriptから自由に操作できるようにメモリ上に構築した木構造のプログラム用モデル」である。
普段私たちがWebサイトでボタンを押して画面の一部が変わったり、アニメーションが動いたりする裏側では、常にこの「DOM」がJavaScriptによってリアルタイムに操作・書き換えられている。
Web開発において「DOMを理解する」ということは、ブラウザが裏側でどのように画面を組み立て、どのようにJavaScriptと連携しているのかという「Webの動く仕組みの原点」を理解することと同義なのである。
