ChromeのHTTP/2サーバプッシュサポート廃止検討と、103 Early Hintsについて

ChromeがHTTP/2サーバプッシュの廃止を検討し始めている。またPreload + 103 Early Hintsの有効性について実験していく模様

背景

HTTP/2(RFC 7540) にはサーバプッシュという機能があります。これは、クライアントからのHTTPリクエストをまたずにサーバがHTTPレスポンスを先行して送ることが出来る機能です。

たとえば、index.htmlに画像1,2,3が含まれているようなページがあるとします。このindex.htmlへのリクエストを受け付けたサーバは、クライアントが画像1,2,3がを要求してくることを予測しサーバプッシュでこれらのリソースを送りつけることが来でます。(クライアント側から、そのリソースが不要であればサーバプッシュをキャンセルすることもできます)

f:id:ASnoKaze:20201113000937p:plain

そうすることで、ページの表示を効率化出来ると考えられていました。

しかし、様々な議論の中で、クライアントがすでにキャッシュを持っているケース、優先制御上デメリットがあるなどの様子が見えてきました。そういった話もありつつ、HTTP/2サーバプッシュは広くは使われていないのが現状です。

そんななか、Chromeの開発者のメーリングリストblink-devで「Intent to Remove: HTTP/2 and gQUIC server push」という投稿がなされました。このメールでは、HTTP/2の現状を鑑みてサーバプッシュのサポートを廃止すること、103 Early Hintsの効果測定をしていく旨が書かれています。

Intent to Remove: HTTP/2 and gQUIC server push

現状

過去28日間で、HTTP/2コネクションでサーバプッシュを受け取った割合は0.05%ほどになっています。
Firefoxでも同じぐらいの数値であることが共有されています)

また、パフォーマンスとしてはAkamaiがあまりかわらないか、特定環境でわずかに向上するという資料が共有されています(リンク)

変更内容

ChromeはHTTP/2とgQUIC(Google版QUIC)でサーバプッシュをサポートしています。なおHTTP/3も仕様上はサーバプッシュ機能を持ちますが、Chromeはサポート予定が無いとのこと。

HTTP/2では通信中にSETTINGSフレームで、サーバプッシュを無効にできますので、Chromeはそれを送信するように変更されます。

Prelaod と103 Early Hints

サーバから突然リソースを送りつけるサーバプッシュではなく、Preload方式を取る方向が検討されています。Preloadでは、必要なリソースURLだけをクライアントに通知し実際にそのリソースを取得するか(キャッシュを利用するか)はクライアントが判断します。クライアントは取得するばあいは通常通りのHTTPリクエストを送信します。

Preloadの指示の仕方は「Preload」で書かれています。

たとえば、index.htmlの要求にするHTTPレスポンスをする際に、styles.cssもプリロードしといてねという風に伝えるには下記のようなレスポンスヘッダをつけます。。

Link: <https://example.com/other/styles.css>; rel=preload; as=style

このPrelaod指示をどれだけ早くクライアントに通知するかの工夫の一環で、2017年に
RFC 8297で「103 Early Hints」という新しい仕組みが標準化されています。

100番台のステータスコードは、継続処理を示すもので、本当の200や404レスポンスよりも前にレスポンスすることが出来ます (100番台のあとには最終的なレスポンスを返す必要があります。)
f:id:ASnoKaze:20201112235610p:plain

一般的にステータスコードが決定するのはHTTPリクエストを完全に処理し終わったあとです。ですので重たいサーバ側処理が完了しないと、いかなるレスポンスヘッダも送り始めることは出来ません(100番台レスポンスを除く)。

そういったケースで、最初の103レスポンス時にLinkヘッダでPreload指示を送ればより早いタイミングでクライアントにPreloadを指示できるようになります。

この103 Early Hintsの有効性について、ChromeとFastlyが共同で実験していくというのがちょうど昨今の動きになります。
www.fastly.com