http/2 push の代替としての 103 Early Hints と Preload
Removing HTTP/2 Server Push from Chrome で案内された通り、HTTP/2 Server Push の実装が Chromium から削除される。
ページロードに必要なリソースを、クライアントからのリクエストを待たずにサーバーから送信することでパフォーマンスの向上を目論んだ仕様だったが、開発者が期待していたような性能の改善が見込めず、HTTP/2 で配信されている Web ページのうちたった 1.25% しかこの機能を使っていなかったことが背景にある。また、HTTP/3 の仕様にも含まれているものの、あまり実装が進んでいない現状がある。
103 Early Hints は新しく追加された HTTP のステータスコードで、例えば 200 のレスポンスに先んじてサーバーから送信される。HTTP レスポンスの 100 番台はインフォメーショナルレスポンスである。
GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]
このリクエストに対して以下のようなサーバーが 200 のレスポンスを構築している間に、次のような 103 のレスポンスを先行して返す。
HTTP/1.1 103 Early Hints
Link: </style.css>; rel=preload
Link: </script.js>; rel=preload
レスポンスヘッダには Preload を用いて、ページの表示に必要なリソースをブラウザに伝えることで、それらの取得を促すことができる。
Preload は HTTP のレスポンスヘッダへの指定だけでなく、HTML の <link>
要素に rel="preload"
属性を付与して、取得したいサブリソースを指定することもできる。
<link rel="preload" href="foo.js" as="script">
<link rel="preload" href="foo.css" as="style">
<link rel="preload" href="foo.png" as="image">
<link rel="preload" href="foo.mp4" as="media">
これらが HTML に記述されていることで、リソースの取得をブラウザに促すことができる。
Web ページの表示には、イニシャルレスポンスである HTML の他に、クリティカルリソースとして CSS や JavaScript といったサブリソースが存在する。ブラウザがこれらのサブリソースをリクエストしてレスポンスを受け取り、DOM および CSSOM を合成して初めて Web ページを描画できる。
そのため、イニシャルレスポンスだけでなくサブリソースのレスポンスもページ表示において重要である。通常、ブラウザは HTML を取得したあとに、上から順にパースしてサブリソースを取得していく。HTML の仕様ではないが Preload scanner のようなブラウザの実装レイヤでの最適化も存在する。
そして Web ページの開発者側ができる最適化として、先程の 103 Early Hints や Preload が存在する。上述の通り、サーバーが HTML を構築する間に先んじて 103 Early Hints を使ってクリティカルリソースをブラウザに伝えておくことでサブリソースのリクエストを促せる。同じく、HTML に記述する <link rel="preload">
もブラウザにサブリソースの取得を促すという点では同等である。
103 Early Hints と HTTP レスポンスヘッダでの Preload の指定はサーバーサイドの実装最適化、一方で HTML での Preload の指定はクライアントサイドの実装最適化として捉えることもできる。
サーバーサイドで 200 OK のレスポンスを作る間にブラウザにリクエストを促すことは、ブラウザの HTML の解釈を待たずに済む。一方で HTML で宣言的に記述できることは、バックエンドと責任分担をしている場合も実装領域においても、「フロントエンドで最適化していること」がわかりやすい。