ベスト プラクティス: HEAD 内の要素の適切な順序

本記事は、マイクロソフト本社の IE チームのブログ から記事を抜粋し、翻訳したものです。 

【元記事】Best Practice_Get your HEAD in order (2011/7/19 6:06 AM)

 

ページを表示する際の最適なパフォーマンスと信頼性を確保するには、HEAD 要素内の各要素の順序に気を付ける必要があります。ここでは、最適な順序と、それが最適である理由を説明します。

HEAD 内の要素の最適な順序
 <doctype> 
     <html> 
         <head> 
             <meta http-equiv content-type charset>  
             <meta http-equiv x-ua-compatible> 
             <base> 
             <title, favicon, comments, script blocks, etc>
なぜ順番が重要か

HEAD 内の要素の順序がなぜ重要かを理解するには、ブラウザーによる Web ページの解析方法と、各要素がページ解析に与える影響を知る必要があります。

ブラウザーは、ページの解析を始めるときに、HTTP 応答の本文のデータも読み取り始めます。

応答の Content-Type ヘッダーに charset 属性が指定されていれば、本文のデータは指定されている文字エンコードを使用したテキストであると即時に解釈できます。しかし、charset 宣言が存在しない場合、ブラウザーは応答本文のデータの読み取りを開始して、先頭の Unicode のバイト順マーク (BOM) の有無、または charset を指定する META HTTP-EQUIV 要素の有無を調べる必要があります。

こうした文字セットの宣言が見つかった時点で、場合によっては、既読のデータを正しく解釈するために、解析を最初からやり直すことが必要になることもあります。このような再実行が発生すると、F12 開発者ツールのコンソールに次のような注意が表示されます。

image

この再実行はパフォーマンスに影響を与える可能性があります。これについてはこの後で説明します。

文字セットの宣言が見つからない場合、ブラウザーは読み取ったデータやその他の要因に基づいてコンテンツのエンコードを強制的に “自動検出” します。しかしこの場合は、Web 開発者の意図とブラウザーの推測が一致しない可能性があります。この不一致の結果、ページやその中のコンテンツが正常に表示されないということもあります。このような理由から、機能性やパフォーマンスのために、エンコード[1] はHTTP 応答ヘッダーで指定するのがベスト プラクティスとなります。何らかの理由で META タグを使って文字セットを指定する必要がある場合は、必ずその META タグが HEAD 内の最初の要素となるようにします。

IE 8 以降では、ページの表示に使用するドキュメント モードをページの作成者が指定できます。これにより、新しいバージョンの IE でも、互換性のためにページを旧バージョンのモードで表示することができます。ドキュメント モードはブラウザーのページ解析方法に影響を与えるので、解析を始めたときに使用されていた最初の X-UA-Compatible 値と違う値を指定する META 要素が見つかると、Internet Explorer は解析プロセスを再実行する必要があります。再実行が必要になると、F12 開発者ツールに以下の注意が表示されます。

image

こうした理由から、X-UA-Compatible 値は HTTP 応答ヘッダーとして指定するのがベスト プラクティスとなります。

何らかの理由で META タグを使って X-UA-Compatible 値を指定する必要がある場合、この META タグはスクリプトより前に置く必要があります。さらに、HEAD 要素内ではできるだけ前の方に置くことが推奨されます

X-UA-Compatible META タグの指定は、場合によって無視されることがあります。たとえば、ドキュメント モードがそれ以前のマークアップ[2] で既に確定されているような場合です。この場合、F12 開発者ツールのコンソールには以下のようなメッセージが表示されます。

image

BASE 要素は、ネットワークから特定のリソースを取得するために、ページ内の相対 URL をどのように絶対 URL に変換するかを制御します。通常、相対 URL はページの URL と組み合わせることによって絶対 URL に変換されますが、BASE タグが存在する場合は、ページの URL ではなく、指定された HREF が URL の生成に使用されます。

BASE 要素は、ページ内のすべての相対 URL の変換に影響するため、ページ内のいずれの相対 URL よりも前に置く必要がありますIE 7 以降、BASE 要素は HEAD 要素内に置くことが必須であり、本文内にあっても無視されることになっています。BASE 要素を JavaScript (たとえば document.write など) を使って指定することは "技術的" には可能ですが、このような方法は使用しないことが強く推奨されます。

必要な文字セット、X-UA-Compatible、BASE 宣言のすべてを指定したら、その後に TITLE 要素など他のマークアップを記述し、HEAD タグを終了します。

Lookahead プリパーサーについて

HTML ページで参照されるスクリプト、スタイルシート、画像などのリソースのダウンロードに伴う遅延を少なくするため、Internet Explorer は、ページ読み込みのできるだけ早い段階でこれらのリソースのダウンロードを要求する必要があります。このときの大きな問題として、ブラウザー パーサーは、標準に従った順序でスクリプトを実行しようとするため、非同期でない、または後に遅らせることができないスクリプト要素に遭遇するとそのまま待機するということがあります。何も対策をしなければ、この待機時間によってページの残りの部分の解析は大きく遅れ、ネットワークへのリソース要求がさらに遅れることになります。

ページ読み込み時のこの問題への対策として、Internet Explorer はパーサーの第 2 のインスタンスを実行します。このパーサーは、メインのパーサーが待機している間に、ダウンロードすべきリソースを検出します。このモードは、その後のマークアップで参照されるリソースを検出するためにメインのパーサーよりも先を読むため、先読み (Lookahead) プリパーサー[3] と呼ばれます。この先読み機能によって開始されたダウンロード要求は、あくまで "推測" と考えられています。たとえば、BASE によって相対 URL の変換方法が変わったなど、メイン パーサーが実行したスクリプトによってその後のマークアップの意味が変化した場合には、推測した要求が無駄になってしまう可能性がある (頻繁ではないとしても、可能性はある) からです。

問題となる可能性があるのは、ドキュメント モードまたは文字セットのためにパーサーを再実行せざるを得ず、Internet Explorer がそのページの途中まで処理した要求をすべて中止してページの解析を改めて再開する場合です。この場合、推測してダウンロードするリソースも探し直します。こういった再実行には、CPU コストだけでなくネットワーク コストもかかります。

たとえば、IE 9 の標準モードから Quirks モードに変わったために再実行されるページについて考えてみましょう。再実行されたことが、以下のように F12 コンソールに表示されます。

image

F12 開発者ツールの [ネットワーク] タブには、推測で行われていたが中止された要求が一覧表示されます。

image

この再実行はページ読み込みのごく初期の段階で発生しているため、実際に URLMon および WinINET でネットワーク要求が行われたのは最初の推測の要求のみです。

Fiddler を使うと、/1.js への中断された要求を確認できます。Reason 列を見ると、最初の要求は元々の html lookahead tokenizer によって、そして後続の (成功した) ダウンロードは再実行された html lookahead tokenizer によって開始されたことがわかります。

image

スクリプト ファイルへの最初の要求は中止されたため、ブラウザーはネットワークからの応答の全体は読み取っていません。ブラウザーはその要求の接続に TCP RST を発行し、すぐに接続を切断しています。再開された後の先読み機能によって同じリソースがダウンロードすべきと認識される場合も、新たな TCP/IP 接続を確立する必要があります。

最高のパフォーマンスを実現するには、ページの文字セットおよび X-UA-Compatible (必要な場合) は HTTP 応答ヘッダーで指定して、コストのかかる再実行をブラウザーに行わせないようにしましょう。

Eric

[1] 迷った場合は UTF-8 エンコードを使用するとよいでしょう。Web コンテンツには、UTF-16 よりも UTF-8 を使用する方がほとんどの場合において効果的です。UTF-16 サポートにはいくつか変則的な点があるため、Web コンテンツでの使用はお勧めしません。

[2] Internet Explorer 10 PPB2 では、バージョン管理のためのプレスキャンが実行された後にパーサーが作業を開始するという新たなアーキテクチャが導入されています。X-UA-Compatible META タグは、本文の最初の 4 kb 以内に配置する必要があり、それ以外の場合無視されます。

[3] いつもこのブログを読んでいる方でしたら、Internet Explorer の先読みダウンロード機能についての記事が記憶にあることでしょう。