PerfData

HTML文書構造

HTML文書構造から学ぶフロントエンドのパフォーマンスチューニング

2023年4月14日
著者: 竹洞 陽一郎

はじめに

フロントエンドとは、画面表示や入力・操作の受け付けなど、主に利用者が直接触れる部分を指します。
WebサイトやWebアプリケーションにおいては、Webブラウザがユーザからの入力・ユーザへの出力のインターフェースとなります。

Form follows function.
形態は機能に従う。

- 建築家ルイス・H・サリヴァン(Louis H. Sullivan)

この名言は、設計思想が構造を決めるという考え方を示しています。
これは、設計やデザイン全般において広く引用されており、機能性や目的を重視し、それに基づいてデザインや構造を決定するべきだと主張しています。
物や建築物、さらにはWebサイトやWebアプリケーションの設計においても、まずその機能や目的を理解し、それに応じた形状や構造を選択することが重要です。

HTMLの構造や役割を理解することは、フロントエンドのパフォーマンスチューニングに大いに役立ちます。
この考え方を適用することで、効率的で高速なフロントエンド周りのWebサイトやWebアプリケーションの実現が可能です。

headとbody

HTML(HyperText Markup Language)は、Webページの構造を記述するためのマークアップ言語です。
まず、HTML文書は、head要素とbody要素から成り立ちます。

head
head要素は、HTML文書に関するメタデータを記述する領域です。
メタデータとは、他のデータに関する情報を提供するデータのことです。
メタデータは、データの構造、内容、意味、品質、関連性、処理方法など、データそのものについての詳細を記述します。
HTML文書の場合、ページのタイトル、文字コード、スタイルシートへのリンク、JavaScriptへのリンク、OGP(Open Graph Protocol)の記載、検索エンジン向けのキーワードや説明文などです。
ページの表示や動作に関わる重要な情報を含んでいますが、通常はブラウザの表示領域に直接表示されません。
body
body要素は、HTML文書の文書データを記述する領域です。
ここには、Webページの実際のコンテンツが記載されます。
テキスト、画像、リンク、フォーム、動画など、ユーザーがブラウザで閲覧するすべての要素が含まれます。
HTMLにおけるheadとbody

ITシステムにおいて、headとbodyの関係は、多くのプロトコルやデータ形式で実装されており、データの整理と伝達に役立っています。
以下に、headとbodyが使用されている具体例をいくつか挙げます。

HTTP(HyperText Transfer Protocol)
Web上でデータをやり取りするためのプロトコルです。
HTTPリクエストとレスポンスには、ヘッダーとボディが存在します。
ヘッダーには、リクエストやレスポンスに関するメタデータ(メソッド、URL、ステータスコード、コンテンツタイプなど)が含まれ、ボディには実際に送受信されるデータが含まれます。
MIME(Multipurpose Internet Mail Extensions)
電子メールの添付ファイルや、HTTPで送信されるコンテンツを扱うための拡張プロトコルです。
MIMEメッセージは、ヘッダーとボディで構成されています。
ヘッダーには、コンテンツタイプやエンコーディング方式などの情報が含まれ、ボディには実際のコンテンツが含まれます。
ファイルフォーマット(例: JPEG、PNG、PDF)
さまざまなファイル形式では、ヘッダーとボディに分けられた構造が採用されています。
ヘッダーには、ファイルタイプやバージョン、ファイル構造に関する情報が含まれ、ボディには実際のデータが含まれます。
通信パケット(例: IPパケット、TCPパケット)
データ通信において、データをパケットという単位に分割して送受信します。
パケットは、ヘッダーとペイロード(ボディ)で構成されています。
ヘッダーには、送信元・送信先アドレス、プロトコル情報、パケットサイズや順序などの情報が含まれ、ペイロード(ボディ)には実際に転送されるデータが含まれます。

HTML、画像、音声、動画、CSS、JavaScript

それでは、Webページを構成する、各ファイルの役割を見ましょう。

Webページを構成するファイルの役割
ファイル役割データ種別
HTMLメタデータと、文書データhead ... メタデータ
body ... データ
画像文書データを補完する画像データデータ
音声文書データを補完する音声データデータ
動画文書データを補完する動画データデータ
CSS文書装飾メタデータ
JavaScript文書機能メタデータ

これらを、先程のheadとbodyの構造図にマッピングしてみます。

HTMLにおけるheadとbodyの構造での各ファイルのマッピング

この構造図から、幾つかの事が自明となります。

1. CSSやJavaScriptはheadに書くべきである

CSS

CSSは文書装飾の役割を果たすため、データではなく、メタデータです。
従って、bodyの中に記載すべきではないです。

HTML Living Standardでは、CSSをhead内に記載すべきである旨を明示的に記述しているわけではありません。
代わりに、style要素に関する記述があり、style要素はメタデータコンテンツであることが示されています。

4.2.6 The style element

JavaScript

JavaScriptは文書機能の役割を果たすため、データではなく、メタデータです。
従って、bodyの中に記載すべきではないです。

HTML Living Standardでは、JavaScriptをhead内に記載すべきである旨を明示的に記述しているわけではありません。
代わりに、script要素に関する記述があり、script要素はメタデータコンテンツであることが示されています。

4.12.1 The script element

2. メタデータ領域とデータ領域を明確に区切ることでメンテナンスが容易になる

データ領域へのメタデータ要素の混入

多くの方がWebサイトのリニューアルを経験されているでしょう。
HTMLの構造を適切に利用し、メタデータとデータを明確に区切って混入を防ぐことで、リニューアル作業が容易になります。
しかし、実務では、データ領域であるbody部にCSSやJavaScriptが記載されていることがあり、作業が困難になることもあるでしょう。

実際に、Webページでは、どのような状況が発生しているでしょうか?
CSSで背景画像を設定し、画像の読み込みが行われることがあったり、body部にインラインでCSSやJavaScriptが書かれていたりします。
また、JavaScriptをbodyの閉じタグの直前に書くとページ読み込みが速くなるという記事を読んで、その方法で実装しているサイトは数多くあります。

そのような実装を避けるために、HTML Living Standardには、scriptタグにdeferという属性が仕様化されており、これを付与すると、同じ効果があります!
さらに、HTMLのパースの最中にダウンロードをしておいてくれるのです!
HTMLのbodyの閉じタグの直前にJavaScriptの読み込みを記述するのは、ファーストフード店でハンバーガーが出来上がってからフライドポテトを揚げるようなものです。

メタデータ領域とデータ領域をきちんと分離することはデータ管理の基本です。
データ管理の基本を守ることで、Webページのデータ品質が向上し、Webサイトのメンテナンスやリニューアルなどにも円滑に対応できるようになります。

適切な文書構造のマークアップによる構造化文書の価値向上

HTMLの文書構造において、コンテキストを十分に考慮せず、div要素が過剰に使用されることがよくあります。
文書構造を適切にマークアップしないと、文書の価値や永続性が低下し、DOMツリー構築の計算コストが増加します。

このような状況を避けるためにも、メタデータ領域とデータ領域を明確に区切り、適切な文書構造を維持することが重要です。
divを使いがちな場面では、「現在コーディングしている要素は、文書構造においてどの部分に該当するのか?」と考えることが役立ちます。
HTML Living Standardで用意されているタグを適切に使用することで、文書のデータ品質が向上します。

これは、SEOにおいても有効で、機械に文書の意味を適切に学習させることができます。
しかし、多くのWebサイトでは、「これは段落、これは表、これは図表、これは引用」といった意味をGoogleのパーサに伝える努力が不足しています。
その結果、品質の低いWebページが増えてしまいます。

既存の仕様に基づいて実装された要素はビルトインと言います。
タグについても、divで新たに定義するより、ビルトインのタグを使用することで、僅かながら高速化が期待できます。
「塵も積もれば山となる」のように、ビルトインされた仕様に基づくタグを適切に使うことで、メンテナンス性も向上します。

適切なマークアップは、ChatGPTにも良い影響を与えます。
自社のWebサイトをChatGPTに適切に理解してもらうために重要です。

「適切なマークアップは、ChatGPTがWebページを学習する際にも効果があるか?」

適切なマークアップによって文書構造を整えることで、効率的なフロントエンド開発が実現できます。

3. CSSとJavaScriptの役割を明確に区別する

例えば、JavaScriptは本来、「文書機能」の実現のために使用されるべきですが、それを「文書装飾」に使用していないでしょうか?
このような使い方をすると、head内のCSSによる文書装飾の役割が混乱し、複雑化してしまいます。
現代のCSSは高機能であり、JavaScriptを使わずにほとんどの機能を実現できます。

遅いWebサイトに共通する特徴の一つとして、モダンなCSSで実現可能なことをJavaScriptを使って実装している点が挙げられます。
これにより、さまざまなライブラリやフレームワークが依存関係を持つことで、実行オーバーヘッドが増加し、ページが遅くなります。
また、メンテナンスコストも指数関数的に増大することがあります。

CSSとJavaScriptの役割を明確に区別し、適切に使用することで、Webサイトのパフォーマンスやメンテナンス性が向上します。
それぞれの技術を効果的に利用することが、効率的なWeb開発に繋がります。

HTML Living Standardの最新仕様に基づくコーディングで実現する高速なWebサイト

高速なWebサイトとはどのようなWebページでしょうか?
計算処理の観点から考えると、以下の要件を満たす必要があります。

HTMLの仕様の発展の歴史を辿ると、HTMLの基本構造を維持しつつ、上記の要件を実現するための仕様が徐々に策定されてきました。
現行の仕様に従ってWebページを制作すると、Webページの描画処理を以下のような流れで効率的に実現できます。

モダンなHTML Living Standardの仕様に基づいた書き方で実現するシンプルなレンダリング処理

しかし、HTMLにインラインでCSSやJavaScriptを記述したり、CSSで可能なことをJavaScriptで実装して文書装飾を行ったりした場合、処理の流れはどう変わるでしょうか。
上記のような整然とした流れではなく、すぐに複雑で混乱した流れになることが容易に想像できます。

このような状況を避け、HTML Living Standardの最新仕様に基づいたコーディングを行うことで、高速で効率的なWebサイトを実現することが可能です。

まとめ

HTMLは、メタデータ領域とデータ領域を分ける目的で、headとbodyという構造が定められました。
さらに、文書、文書装飾、文書機能の役割を担うために、HTML、CSS、JavaScriptが存在し、それぞれの適切な場所がデータ領域かメタデータ領域かによって決まります。
これらの前提に基づき、HTMLは仕様を改訂し続けています。

構造を理解することで、仕様の理解が深まり、さらに機能の理解が向上します。
役割の混同を避けることで、「美しい」実装が可能になり、「美しい」実装は計算コストの低減につながります。

このように、HTMLの構造や役割を理解し、適切な実装を行うことで、効率的で高速なフロントエンド処理を実現することが可能です。