Skip to content
Artwork for 八百万のOSS
八百万のOSS · August 11 · 57 min

#15 103 Early Hints、返すだけでは速くならない

103 Early Hintsは、最終的なHTMLが完成する前に、必要になりそうなCSSやJavaScriptを`Link`ヘッダーでブラウザへ知らせる仕組みです。ただし、103を返すだけでページが速くなるわけではありません。今回catatsuyが紹介するEarly Hintsについて、初めて聞くhentekoが仕組みから実運用の注意点まで質問しながら掘り下げます。 前半では、現在は主要ブラウザから削除されたHTTP/2 Server Pushから振り返ります。サーバーにはブラウザのキャッシュ状態が分からず、不要なリソースまで送ってしまう問題がありました。H2Oはこの問題に対して、ブラウザが持っていると推測されるリソースを`h2o_casper` Cookieで管理するCASPerを実装しました。さらに、その発想をHTTP/2へ一般化するCache Digestsも提案されましたが、標準化には至りませんでした。Early HintsではリソースそのものをPushせず、取得するかどうかをブラウザに委ねることで、この役割分担を変えています。 後半では、SSRでHTMLを生成している間にCSSやJavaScriptの取得を進める仕組み、CDN Edgeから早く返す利点、fingerprint付きassetとデプロイ世代の同期問題を取り上げます。nginx 1.29.0の`early_hints`ディレクティブはupstreamから届いた103を転送する機能であり、nginx自身が103を生成するものではありません。また、HTTP/2・HTTP/3かつ`Sec-Fetch-Mode: navigate`に対象を絞る理由や、nginx 1.29.7以降ではproxy先のデフォルトがHTTP/1.1に変わったことも紹介します。 Early Hintsで重要なのは、確実に使う少数のリソースだけをHintし、端末別に計測することです。Shopifyの観測データの事例も参照しながら、preloadするリソースを増やしすぎると逆効果になり得ることや、実際にLCPが改善したかを確認する必要性まで考えます。 - Early Hintsの解説(Chrome for Developers): https://developer.chrome.com/docs/web-platform/early-hints - Remove HTTP/2 Server Push from Chrome(Chrome for Developers): https://developer.chrome.com/blog/removing-push - H2O HTTP/2 Directives — http2-casper: https://h2o.examp1e.net/configure/http2_directives.html - Cache Digests for HTTP/2(IETF Datatracker): https://datatracker.ietf.org/doc/draft-ietf-httpbis-cache-digest/ - RFC 8297: An HTTP Status Code for Indicating Hints: https://datatracker.ietf.org/doc/html/rfc8297 - NGINX Introduces Support for 103 Early Hints: https://blog.nginx.org/blog/nginx-introduces-support-103-early-hints - nginx Issue #779 — Enable Early Hints 103 without upstream support: https://github.com/nginx/nginx/issues/779 - Keep-alive to upstreams is now default in NGINX 1.29.7: https://blog.nginx.org/blog/keep-alive-to-upstreams-is-now-default-in-nginx-1-29-7 - Fastly Early Hints documentation: https://www.fastly.com/documentation/reference/http/early-hints/ - Fastly VCL `early_hints()`: https://www.fastly.com/documentation/reference/vcl/functions/tls-and-http/early-hints/ - FastlyとYottaaのEarly Hints導入事例: https://www.fastly.com/jp/blog/how-fastly-and-yottaa-transform-site-performance-with-early-hints - Early Hints at Shopify(Performance @ Shopify): https://performance.shopify.com/blogs/blog/early-hints-at-shopify 関連リンク: - 103 Early Hints(MDN): https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Status/103 - Sec-Fetch-Mode(MDN): https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Headers/Sec-Fetch-Mode - Next.js: https://nextjs.org/ - Go `net/http`: https://pkg.go.dev/net/http - Lighthouse(Chrome for Developers): https://developer.chrome.com/docs/lighthouse/overview - CrUX(Chrome UX Report): https://developer.chrome.com/docs/crux - New Relic: https://newrelic.com/ ───────────── YouTube: https://youtu.be/jFyg4t3hK80 Web: https://yaoyorozu-oss.henteko07.com/ X: https://x.com/yaoyorozu_oss

0:00-57:42

transcript

No transcript — this publisher did not publish one.

show notes

103 Early Hintsは、最終的なHTMLが完成する前に、必要になりそうなCSSやJavaScriptを`Link`ヘッダーでブラウザへ知らせる仕組みです。ただし、103を返すだけでページが速くなるわけではありません。今回catatsuyが紹介するEarly Hintsについて、初めて聞くhentekoが仕組みから実運用の注意点まで質問しながら掘り下げます。


前半では、現在は主要ブラウザから削除されたHTTP/2 Server Pushから振り返ります。サーバーにはブラウザのキャッシュ状態が分からず、不要なリソースまで送ってしまう問題がありました。H2Oはこの問題に対して、ブラウザが持っていると推測されるリソースを`h2o_casper` Cookieで管理するCASPerを実装しました。さらに、その発想をHTTP/2へ一般化するCache Digestsも提案されましたが、標準化には至りませんでした。Early HintsではリソースそのものをPushせず、取得するかどうかをブラウザに委ねることで、この役割分担を変えています。


後半では、SSRでHTMLを生成している間にCSSやJavaScriptの取得を進める仕組み、CDN Edgeから早く返す利点、fingerprint付きassetとデプロイ世代の同期問題を取り上げます。nginx 1.29.0の`early_hints`ディレクティブはupstreamから届いた103を転送する機能であり、nginx自身が103を生成するものではありません。また、HTTP/2・HTTP/3かつ`Sec-Fetch-Mode: navigate`に対象を絞る理由や、nginx 1.29.7以降ではproxy先のデフォルトがHTTP/1.1に変わったことも紹介します。


Early Hintsで重要なのは、確実に使う少数のリソースだけをHintし、端末別に計測することです。Shopifyの観測データの事例も参照しながら、preloadするリソースを増やしすぎると逆効果になり得ることや、実際にLCPが改善したかを確認する必要性まで考えます。


- Early Hintsの解説(Chrome for Developers): https://developer.chrome.com/docs/web-platform/early-hints

- Remove HTTP/2 Server Push from Chrome(Chrome for Developers): https://developer.chrome.com/blog/removing-push

- H2O HTTP/2 Directives — http2-casper: https://h2o.examp1e.net/configure/http2_directives.html

- Cache Digests for HTTP/2(IETF Datatracker): https://datatracker.ietf.org/doc/draft-ietf-httpbis-cache-digest/

- RFC 8297: An HTTP Status Code for Indicating Hints: https://datatracker.ietf.org/doc/html/rfc8297

- NGINX Introduces Support for 103 Early Hints: https://blog.nginx.org/blog/nginx-introduces-support-103-early-hints

- nginx Issue #779 — Enable Early Hints 103 without upstream support: https://github.com/nginx/nginx/issues/779

- Keep-alive to upstreams is now default in NGINX 1.29.7: https://blog.nginx.org/blog/keep-alive-to-upstreams-is-now-default-in-nginx-1-29-7

- Fastly Early Hints documentation: https://www.fastly.com/documentation/reference/http/early-hints/

- Fastly VCL `early_hints()`: https://www.fastly.com/documentation/reference/vcl/functions/tls-and-http/early-hints/

- FastlyとYottaaのEarly Hints導入事例: https://www.fastly.com/jp/blog/how-fastly-and-yottaa-transform-site-performance-with-early-hints

- Early Hints at Shopify(Performance @ Shopify): https://performance.shopify.com/blogs/blog/early-hints-at-shopify


関連リンク:

- 103 Early Hints(MDN): https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Status/103

- Sec-Fetch-Mode(MDN): https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Headers/Sec-Fetch-Mode

- Next.js: https://nextjs.org/

- Go `net/http`: https://pkg.go.dev/net/http

- Lighthouse(Chrome for Developers): https://developer.chrome.com/docs/lighthouse/overview

- CrUX(Chrome UX Report): https://developer.chrome.com/docs/crux

- New Relic: https://newrelic.com/


─────────────

YouTube: https://youtu.be/jFyg4t3hK80

Web: https://yaoyorozu-oss.henteko07.com/

X: https://x.com/yaoyorozu_oss