.png?q=75&fm=webp)
DOMとは?仕組みをわかりやすく解説!「過大なDOMサイズの回避」の改善策も
Webページを構成する重要な概念の一つが「DOM(Document Object Model)」です。
本記事では、DOMの基本概念から仕組み、そして表示速度向上のための「過大なDOMサイズの回避」手法まで詳しく解説します。
DOMとは?
DOM(Document Object Model)とは、HTMLなどの要素をJavascriptなどのプログラムで操作できるように構造化したモデルのことです。
DOMの仕組みや動き方の解説の前に、ブラウザの読み込みの流れから解説していきます。
ブラウザの読み込みの流れ
まず、ウェブページへアクセスすると、ブラウザがサーバーへリクエストを送り、HTMLファイルを取得します。
ブラウザがHTMLを受け取ったあとは、HTMLを上から順番に内容を解析していきます。
読み込まれたHTMLの情報をDOMに変換されます。
Webブラウザは読み込んだHTMLファイルを解析し、要素(タグ)同士の親子関係や階層構造を持つ「ツリー構造」として表現します。
変換されたDOMを使って実際閲覧のできる状態に描写されるという流れになります。
DOMツリー構造について
DOMの構造はツリー構造と呼ばれるものです。
この構造は「ツリー」という名前の通り、木の枝のように上から下へと分岐していく形をしています。
DOMもたくさんのオブジェクトから構成されていて、この1つ1つのオブジェクトはノードと呼ばれます。
上記の画像はツリーのイメージですが、下記がDOMツリーのソース例です。
「▼」をクリックすると、その下の階層が表示され、さらに「▼」をクリックするとより深い階層が見られます。
▼ <html>
▼ <head>
▼ <title>
▼ <body>
▼ <h1>
▼ <p>例えば、<html>要素が最上位の親となり、その下に<head>や<body>要素が子として配置され、さらにその下に<h1>や<p>などの要素が階層的に並びます。
各要素は「ノード」と呼ばれ、親ノード、子ノード、兄弟ノードという関係性で管理されています。
この明確な階層構造により、JavaScriptは特定の要素を効率的に検索・操作でき、「親要素から子要素へ」「兄弟要素間の移動」といった柔軟なナビゲーションが可能になります。
DOM操作について
DOMは画面の描画と連動していて、DOMのノードを変更すると変更した内容がすぐページに反映されます。
JavaScriptはこのDOMを通じて、ページ上の要素を動的に追加・削除・変更することができ、ユーザーの操作に応じてリアルタイムでコンテンツを更新できます。
つまり、DOMはWebページの「設計図」として機能し、静的なHTMLを動的なWebアプリケーションへと変貌させる重要な基盤技術なのです。
例えば、document.getElementById()で特定の要素を取得し、innerHTMLでテキスト内容を変更したり、style.colorで文字色を変更できます。
また、addEventListener()でクリックやキー入力などのユーザー操作に反応する機能も実装可能です。
さらに、createElement()で新しい要素を作成し、appendChild()でページに追加することで、ユーザーの操作に応じてリアルタイムでコンテンツを更新できます。
これらのDOM操作により、フォームの入力チェック、画像の切り替え、メニューの開閉など、インタラクティブなユーザー体験を提供することが可能になります。
このようにページの見た目を動的に変えるためにDOMのノードを変更することをDOM操作といいます。
過大なDOMサイズが大きくなると発生する問題点
DOMサイズが大きくなると、初期の表示速度の低下やメモリ使用量の急激な増加、レンダリング処理の重負荷化が発生します。
これらの要素は、Core Web Vitalsの指標の悪化に影響し、SEOランキングにも悪影響を与えるため注意が必要です。
特に下記のような問題が発生しやすくなります。
表示速度の遅延やレンダリング遅延(FCP・LCPにも影響)
DOMノードが多いほどHTMLファイルのサイズが大きくなり、ダウンロード時間が延長されます。
初回ページ読み込みで3秒以上かかる場合、離脱率にもつながります。
ブラウザがHTMLを解析してDOMツリーを構築する時間が長くなります。
特にFCP(First Contentful Paint)やLCP(Largest Contentful Paint)の時間が悪化しSEO評価にも影響を及ぼします。
DOM構造が複雑になることで、レイアウト変更時の再計算処理が重くなります。処理時間が指数関数的に増加するなど全体的なレンダリング処理の遅延にもつながります。
LCPやFCPについて詳しくは下記の解説ページをご覧ください。
ユーザーインタラクションの応答遅延(INPにも影響)
過大なDOMサイズにより、クリックやタップなどのユーザー操作に対する視覚的フィードバックまでの時間が200ms以上に延長され、INP(interaction to next paint)スコアが悪化します。
DOM検索処理やイベント処理が重くなることで、スクロールがカクつき、フォーム入力での文字入力やフォーカス移動も遅延します。
メインスレッドが長時間ブロックされるLong Taskが頻発し、ユーザーが操作に対する即座の反応を感じられず、サイトが「重い」「反応しない」という印象を与えてしまいます。
INPについて詳しくは下記の解説ページをご覧ください。
INP(interaction to next paint)
メインスレッドのブロック(TBTにも影響)
TBT(Total Blocking Time)への影響で、DOM操作を行うJavaScript処理がメインスレッドを長時間ブロックし、ユーザーインタラクションへの応答性が著しく低下します。
このように、DOM要素はWebページのパフォーマンスへの影響が大きく最適に活用する必要があります。
TBTの指標について詳しくは下記のページで解説しています。
メモリ消費量の急激な増加(クラッシュする可能性)
過大なDOMサイズは、各DOMノードとそのスタイル情報がメモリ上に保持されるため、ノード数に比例してメモリ消費量が急激に増加します。
これにより、低スペックデバイスではブラウザクラッシュのリスクが高まり、CPU使用率の上昇によりバッテリー消費も増大します。
メモリ消費量が増えることで、パソコン自体が重くなりサイトからの離脱も考えられます。
PageSpeed Insightsの「DOM サイズを最適化する」の改善項目
PageSpeed Insightsでは「過大なDOMサイズの回避」として具体的な基準値が設定されており、とても重要な要素と言えます。
DOM サイズが大きいと、スタイルの計算とレイアウトのリフローに時間がかかり、ページの応答性に影響する可能性があります。DOM サイズが大きいと、メモリ使用量も増加します。
項目には上記のような改善項目が記述がされています。
PageSpeed InsightsのDOM要素の推奨基準
DOM要素数が1,400個を超える、階層の深さが32層を超える、親要素あたりの子要素が60個を超える場合に警告が表示されます。
項目 | 理想値 | 実用的な目標 | アラートが出る数値 |
|---|---|---|---|
DOM要素数 | 500個以下 | 800個以下 | 1,400個以上 |
DOM階層 | 8層以下 | 15層以下 | 32層以上 |
子要素数 | 10個以下 | 30個以下 | 60個以上 |
理想値としては、DOM要素数が500個以下、階層の深さが8層以下、親要素あたりの子要素が10個以下が理想ですが、できる限りここを目指してみてください。
この数値はウェブサイトを運営している方は抑えておきたい指標になるので、チェックしておきましょう。
「DOM サイズを最適化する」の具体的な改善策
DOMサイズも最適化することで、表示速度を含めユーザー体験を上げることができます。
下記に具体的な改善案をまとめます。
不要な要素の削除とHTMLの構造最適化
改善提案の1つとして、不要な入れ子構造の削除、装飾目的のみの空<div>要素の除去、ReactやVueでのフラグメント活用による冗長なWrapper要素の削減が推奨されます。
下記のソース例のように、無駄な要素をまとめるなどしてDOM要素や階層の削減が実現できます。
<!-- 悪い例 -->
<div class="wrapper">
<div class="container">
<div class="section">
<p>コンテンツ</p>
</div>
</div>
</div>
<!-- 良い例 -->
<section class="content">
<p>コンテンツ</p>
</section>セマンティックHTMLの活用
また、過剰なネスト構造をセマンティックなHTML5要素(<header>, <main>, <section>等)に置き換え、階層を3-5レベル以内に制限することで構造を簡略化します。
CSSでレイアウト可能な箇所のHTML簡略化と、重複するコード統合により、メンテナンス性とパフォーマンスが大幅に向上します。
<!-- 悪い例 -->
<div class="header">
<div class="title">見出し</div>
</div>
<!-- 良い例 -->
<header>
<h1>見出し</h1>
</header>コンテンツの分割とページネーションの実施
長文記事やコンテンツなどのページ分割をすることも改善につながります。
コンテンツも重要な要素ではありますが、無駄に長いページや内容に一貫性のないコンテンツなどはページ分割をすることでDOMサイズの回避につながります。
下記のような例は特に改善の余地があります。
- 何百という商品一覧があるページ→1ページ20商品などに分けページネーションで分ける
- 何万文字もあるようなコンテンツ→テーマに分けてページを作成する
- スクロールで永遠に読み込まれる形式で長文コンテンツ→読み込み形式をやめページを分ける
外部埋め込みコンテンツの遅延読み込み
TwitterやInstagram投稿、YouTube動画、Google Maps、広告バナーなどの外部コンテンツを多数埋め込むと、各サービスが独自のHTML構造やJavaScriptを追加するため、DOMサイズが急激に増大します。
これらを遅延読み込みをすることで過大なDOMサイズの回避することができます。
あくまで目安ですが、下記のように大きな変化が見込めます。
外部コンテンツ | 通常のDOM要素数 | 遅延読み込み時 | 削減率 |
|---|---|---|---|
YouTube動画 | 200〜300個 | 3〜5個 | 95%〜98% |
Twitter投稿 | 150〜250個 | 2〜4個 | 96%〜98% |
Instagram投稿 | 100〜200個 | 2〜3個 | 97%〜98% |
Google Maps | 300〜500個 | 5〜10個 | 95%〜97% |
広告ウィジェット | 50〜150個 | 1〜2個 | 95%〜98% |
特にSNS埋め込みは1つの投稿で数十から数百のDOM要素を生成し、複数配置すると深刻なパフォーマンス低下を引き起こします。
また、マーケターにはよく利用されるGTMタグも原因となります。
これらの外部コンテンツは、それぞれが独自のDOM構造を持っているため、改善のやり方によってはページ全体のDOM要素数を大幅に増加させます。
参考ソース
<!-- 通常の埋め込み(初期DOM重い) -->
<iframe src="https://www.youtube.com/embed/VIDEO_ID"
width="560" height="315"></iframe>
<!-- + YouTubeが内部で生成する大量のDOM要素 -->
<!-- 遅延読み込み(初期DOM軽い) -->
<div class="lazy-youtube" data-video-id="VIDEO_ID">
<img src="thumbnail.jpg" alt="動画サムネイル">
<button class="play-button">再生</button>
</div>DOMのまとめ
DOMはWebページの基盤となる重要な技術であり、HTML文書をブラウザが理解しやすい階層構造として表現するものです。
これらの対策を適切に実施することで、FCP、LCP、TBTなどのコアウェブバイタル指標が大幅に改善され、SEO効果の向上とユーザー満足度の向上を同時に実現できます。
DOMの最適化は、現代のWeb開発において不可欠な取り組みといえるでしょう。
表示速度の改善は一度やって終わりではありません。コンテンツの更新、新機能の追加、デザインの変更など、サイトの成長と共に継続的な最適化が必要です。
