読み込みが速い HTML ページを作成するための豆知識
===========================

これらの豆知識は、一般の知識や実験に基づくものです。

ウェブページを最適化すると、訪問者に対して応答性のよいサイトを提供するだけでなく、ウェブサーバーやインターネット接続の負荷を低減する効果もあります。これは大規模なサイトや、緊急事態で通信量が急増するニュース速報のようなサイトでは重要でしょう。

ページの読み込みパフォーマンスの最適化は、低速なダイヤルアップ接続やモバイルデバイスの利用者向けコンテンツのためだけではありません。ブロードバンド向けコンテンツでも重要であり、高速接続の利用者であっても劇的な改善につながるでしょう。

豆知識
---

### ページの量の削減

ページの量は、ページ読み込みパフォーマンスにおいて断然重要な要素です。

最小化として知られる不要なホワイトスペースやコメントの削除、インラインのスクリプトや CSS の外部ファイルへの移動によりページの量を削減することで、ページの構造変更を最小限にしてダウンロードの性能を向上できるでしょう。

HTML Tidy のようなツールを利用すると、妥当な HTML ソースから行頭のホワイトスペースや過剰な空行を自動的に取り除くことができます。他に JavaScript ソースを、書式変更や難読化および長い識別子を短いものに置き換えることで 「圧縮」するツールもあります。

### ファイル数の最少化

ウェブページが参照するファイル数を削減することで、ページのダウンロードに必要な HTTP コネクションの数が減り、それによってリクエストを送信したり、レスポンスを受け取ったりする時間が短縮できます。

ブラウザーのキャッシュ設定によっては、ブラウザーが各ファイルの `If-Modified-Since` ヘッダーで、ファイルが最後にダウンロードされてから変更されているかどうかを確認するリクエストを送信することがあります。ページをレンダリングする前に、ブラウザーがこれらの各ファイルの変更時刻をチェックする必要があるため、参照されたファイルの最終変更時刻をチェックするのに時間がかかり過ぎると、ウェブページの初期表示が遅くなることがあります。

CSS で多数の背景画像を使用している場合は、画像スプライトと呼ばれる方法でで画像を 1 つに結合することで必要な HTTP による参照の数を減らすことができます。すなわち、背景として用いる画像ファイルは毎回同じものを適用し、それを適切な x/y 座標に調整します。これは寸法が限られている要素について最善の方法ですが、適用できない場合もあるでしょう。しかし、HTTP リクエストを少なくしてキャッシュする画像を単一にすることで、ページの読み込み時間を削減できます。

### コンテンツ配信ネットワーク (CDN) を使用する

この記事の目的のために、CDN はサーバーと訪問者の間の物理的な距離を縮めるための手段です。サーバーの起点と訪問者の間の距離が長くなると、読み込み時間が長くなります。ウェブサイトのサーバーがアメリカにあり、インドからの訪問者がいるとします。米国からの訪問者と比較して、ページの読み込み時間はインドの訪問者の方がはるかに長くなります。

CDN は地理的に分散したサーバーネットワークで、ユーザーとウェブサイトの距離を縮めるために連携して機能します。CDN はキャッシュされたウェブサイトのバージョンを保存し、それらをユーザーに最も近いネットワークノードを介して訪問者に提供するので、待ち時間が短縮されます。

参考文献:

* Understanding CDNs
### ドメイン検索の削減

ドメインが分かれていると DNS の参照に時間がかかるため、CSS の link や JavaScript や画像の src に多数のドメインが現れるほど、ページの読み込み時間が長くなるでしょう。

現実的でない場合があるかもしれませんが、ページがあるドメインと異なるドメインの使用数は必要最低限にするよう注意すべきです。

### 再利用されるコンテンツのキャッシュ

どんなコンテンツでも、キャッシュできるか、キャッシュされているか、キャッシュ期限が適切であるかを確認してください。

特に、`Last-Modified` ヘッダーに注意してください。これは、効率のよいページのキャッシュができるようにします。このヘッダーは、ファイルを読み込もうとしているユーザーエージェントに、ファイルがいつ更新されたかなどの情報を伝えます。多くのウェブサーバーは、静的なページ (`.html`、`.css` など) にはファイルシステムに格納されている最終更新日に基づいて、自動的に `Last-Modified` ヘッダーを追加します。もちろん、動的なページ (`.php`、`.aspx` など) については取得できないので、ヘッダーを送信しません。

そのため、特に動的に生成されるページについては、この件について調べてみると有益です。少し厄介ですが、通常キャッシュできないページのリクエストを大幅に節約できるでしょう。

詳細情報:

1. HTTP Conditional Get for RSS Hackers
2. HTTP 304: Not Modified
3. Wikipedia の HTTP ETag の記事
4. Caching in HTTP
### ページのコンポーネントの最適な順序

最初の表示に必要な CSS または JavaScript と共に、ページコンテンツをまずダウンロードすると、ページの読み込み中にユーザーに最もすばやくページを表示させることができます。このコンテンツは通常テキストであるため、転送中のテキスト圧縮の効率が良く、ユーザーへの反応がもっと早くなります。

使用される前にページの読み込みが完了する必要がある動的機能は、最初は無効にしておき、ページの読み込みが完了した後でのみ有効にするようにしましょう。これにより、JavaScript がページコンテンツの後に読み込まれるようになり、ページ読み込み時に全体が表示されるまでの時間が短縮されます。

### インラインスクリプト数の削減

インラインスクリプトがあると、インラインスクリプトのパース中にページの構造が変わる可能性があるとパーサーが想定しなければならないため、ページの読み込みにおいて重荷になることがあります。一般的にはインラインスクリプトの使用を減らし、また特に `document.write()` を用いたコンテンツの出力を減らすことで、ページ読み込みのパフォーマンスが向上するでしょう。 `document.write()` に基づく旧来のコンテンツ操作方法ではなく、最新のブラウザー向けの方法である AJAX を使用してください。

### 最新の CSS と正しいマークアップの使用

最新の CSS を用いるとマークアップの量を削減し、レイアウトの点で (スペーサーの) 画像使用を減らし、また多くの場合スタイル付けした文字列の画像を置き換えることが可能です。画像は CSS と文字列の組み合わせに比べ、多大なコストがかかります。

正しいマークアップを使用することは、ほかにも利点があります。第一に、ブラウザーが HTML を解釈する際にエラー訂正を行う必要がなくなります (ユーザーの記述法の多様性を認めるかどうかという哲学的な問題とは別です。厳密な、許容範囲のない書式を強制するというより、プログラム的に「正しく」または正規化しましょう)

さらに、正しいマークアップをすることによって、ウェブページを*プリプロセス*ができる他のツールが自由に利用できるようになります。例えば、HTML Tidy はホワイトスペースや省略可能な終了タグを除去することができます。しかし、重大なマークアップの誤りがあるページではツールを実行できません。

### コンテンツをまとめる

テーブルをレイアウトのために使うのは陳腐化した方法であり、もはや使うべきではありません。レイアウトを行うには、代わりに浮動要素、位置指定、フレックスボックス、グリッドを使用してください。

テーブルは現在でも妥当なマークアップと考えられていますが、表形式のデータを表示するために用いるべきです。ブラウザーがページを迅速に表示するためには、テーブルを入れ子にしないようにしてください。

以下のように深い入れ子のテーブルを使用する代わりに、
```

<table>
  <table>
    <table>
          ...
    </table>
  </table>
</table>
```


以下のように入れ子にしないテーブルや div を用いてください。
```

<table>...</table>
<table>...</table>
<table>...</table>
```


CSS Flexible Box Layout と CSS Grid Layout の仕様書も参照してください。

### SVG の資産を最小化し圧縮する

多くの描画アプリケーションで作成された SVG は、不必要なメタデータを含んでいることが多く、削除することができます。サーバーで SVG 資産を gzip で圧縮するよう設定しましょう。

### 画像を縮小して圧縮する

画像が大きいと、ページの読み込みに時間がかかります。画像をページに追加する前に、圧縮することを検討してください。 Compress Jpeg、Tiny PNG、その他多くのツールがオンラインで利用可能です。photoshop などのオフラインツールも使用できます。

### 画像やテーブルのサイズ指定

ブラウザーが直ちに画像やテーブルの高さや幅を決めることができれば、ブラウザーはコンテンツの再配置を行うことなくウェブページを表示できます。これはページの表示を高速化するだけでなく、ページの読み込みが完了するまでにレイアウトが不安定に変化することを防ぎます。よって、可能な限り画像には `height` と `width` を指定するべきです。

テーブルは以下のセレクターとプロパティの組み合わせを用いるべきです:
```

  table-layout: fixed;
```


そして、 `<col>` 要素および `<colgroup>` 要素を用いて列の幅を指定しましょう。

### 画像の遅延読み込みを使用する

既定では、画像は**熱心に**読み込まれます。つまり、 HTML で処理されると同時に画像が読み込まれ、表示されます。熱心に読み込まれた画像は、文書の `load` イベントが送られる前に表示されます。画像の遅延読み込みに切り替えるとブラウザーは、視覚的ビューポートの描画に必要になるまで、画像の読み込みを保留します。

画像に遅延読み込みのマークを付けるには、 `loading` 属性に `lazy` という値を指定してください。この設定により、画像は必要なときにのみ読み込まれます。


```html
<img href="./images/footerlogo.jpg" loading="lazy" />
```


ただし、遅延読み込みされた画像は、 `load` イベントが発生した時点では利用できない場合があります。画像がロードされているかどうかは、論理的プロパティの `complete` の値が `true` であるかどうかを確認することで判断できます。

### ユーザーエージェント要件の賢い選択

ページデザインを最大限に改善するには、プロジェクトのユーザーエージェントの要件を合理的なものにしましょう。すべてのブラウザー、特に古いバージョンのブラウザーでコンテンツがピクセル単位で正確に見えるように要求しないでください。

理想的には、適切な標準仕様に対応している最新のブラウザーを最低要件にするよう考慮するべきです。これには、最近のバージョンの Firefox、Internet Explorer、Google Chrome、Opera、Safari が含まれます。

ただし、この記事に記載している秘訣の多くはあらゆるユーザーエージェントに適用できる汎用的なテクニックであり、かつブラウザーの対応要件にかかわらずどのようなウェブページにでも適用できます。

### 可能なら async や defer を使用する

async と defer 属性の両方と互換性のある JavaScript を使用し、特に、複数の script 要素がある場合、可能ならば async をいつでも使用してください。

これにより、ページで JavaScript が読み込み中である間はレンダリングを中断できます。さもなければ、ブラウザーはこれらの属性を持たない script 要素の後にあるコンテンツをレンダリングしないでしょう。

注意: これらの属性が初回のページ読み込みに大きな効果があるとしても、属性は使用するべきですがすべてのブラウザーで動作するとは考えないようにしてください。よい JavaScript コードを作るためのガイドラインすべてに従っていれば、コードを変更する必要はありません。

ページ構造の例
-------

* ``<html>``
* ``<head>``
    + :
     
    ``<link>`` ...
    
    ページの外観に必要な CSS ファイルです。管理しやすくするため、関連性のない CSS は別のファイルに分けるとともに、パフォーマンスのためにファイル数は最小限にしてください。
    
    
    
    ``<script>`` ...
    
    
     ページの読み込み中に**必要な**機能の JavaScript ファイルですが、ページの読み込み後にしか実行しない対話操作に関するものは含めないようにしてください。
     管理のために関連性のない JavaScript は別のファイルに分けるとともに、パフォーマンスのためにファイル数は最小限にしてください。
* ``<body>``
    + : ユーザーが閲覧可能なページコンテンツを小さな塊 ( ``<header>``/ ``<main>`/` ``<table>``) にまとめると、ページ全体のダウンロードを待たずに表示できるようにすることができる。
     
    ``<script>`` ...
    
    
     対話操作を実行するのに用いるスクリプトです。対話操作のスクリプトはたいてい、ページが完全に読み込まれて必要なオブジェクトがすべて初期化された後にのみ実行されます。よって、ページのコンテンツより先に読み込む必要はありません。先に読み込むと、ページが最初に表示されるのが遅くなります。
     管理のために関連性のない JavaScript は別のファイルに分けるとともに、パフォーマンスのためにファイル数は最小限にしてください。
     ロールオーバー効果で用いる画像がある場合は、ページのコンテンツをダウンロードした後に画像の先読みをしておきましょう。
関連リンク
-----

* 書籍: "Speed Up Your Site" by Andy King (英語)
* Yahoo! によるすばらしい完成された ウェブサイト高速化のためのベストプラクティス (英語)
* パフォーマンス解析・最適化向けツール: Google PageSpeed Tools
* Paint Flashing Tool