以下の内容はhttps://tech.repro.io/entry/2025/01/28/125334より取得しました。


103 Early Hints とは何か? ~マイナーだけど革新的なHTTPステータスの世界~

はじめに

みなさまこんには。日々 Booster で楽しくコードを書いている杉浦(sugi) です。 Booster プロジェクトではタグを入れるだけでサイトを高速化できる「Repro Booster」という製品を作っていますが、そのためにも日々さまざまな最適化手法を調査・模索しています。

その中で個人的に期待しているのが、 103 Early Hints というHTTPステータスコードです。 この記事では Repro Tech Meetup #9 で行った発表(資料)を元に、103 Early Hintsはどのような仕組みなのか、なぜ高速化につながるのか、さらに現状の実装に関して解説します。

ちょっとマイナーな内容ですが、知っておくとウェブパフォーマンス最適化の大きな武器になるかもしれません。

103 Early Hintsの背景

従来のHTTP通信の課題

通常のHTTP通信においては、ブラウザはサーバーから最初のレスポンス(例:200 OK)を受け取るまで、ページを描画するために必要なCSSJavaScript、画像などの外部リソースを先行して取得できません。

この最初のレスポンスの返却には、伝統的な動的 Web アプリケーションではある程度の時間がかかります。その間、ブラウザ側は「サーバーからレスポンスが届くまで待機」している状態に陥ってしまい、実際にリソース取得が始まるのはレスポンスを受け取ってから、というのが一般的な動きでした。

103 Early Hints の登場

この「待ち時間」を何とか有効活用できないかと考えた末に登場したのが 103 Early Hints になります。

100番台のレスポンスコードは馴染みが無いですが、実は HTTP/1.1 の頃から定義が存在しています。この100番台の応答を利用すると、1回のリクエストに対して複数のレスポンスを返却できます。

これを利用し、サーバーが最終的なレスポンスをまだ用意できていない段階で、「この後必要になるであろうリソース」をあらかじめブラウザに示し、先行してダウンロードしておいてもらうというアプローチになります。

サーバーがレスポンスの本体を返し終わる頃には、ページ表示に不可欠なスタイルシートスクリプトのダウンロードが既に完了しており、結果的にページの描画を大幅に高速化することが期待できるのです。

103 Early Hintsの仕組み

フロー概要

  1. クライアントからのリクエス
    ユーザーがウェブページを開くと、まずブラウザからサーバーへHTTPリクエストが送信されます。
  2. サーバーが103 Early Hintsを返す
    サーバーはリクエストを受け取り、本レスポンス(通常は200 OKなど)を準備する前に、まずヘッダ情報だけを含む 103 Early Hints ステータスコードを返します。ここに、後で必要になるリソース(CSSJavaScriptファイルなど)のリンク情報を含めます。 text HTTP/1.1 103 Early Hints Link: </style.css>; rel=preload; as=style Link: </main.js>; rel=preload; as=script
  3. ブラウザがリソースを先行取得
    ブラウザは 103 Early Hints で通知された「プリロードするべきリソース」の情報を読み取り、サーバーが本レスポンスを送信してくる前に、リソースのダウンロードを開始します。
  4. 最終的なレスポンスの受信と描画
    サーバーが準備でき次第、本レスポンス(通常の 200 OK など)とHTML本文を返送します。ブラウザ側では既にスタイルシートスクリプトがダウンロード済みのため、ページ描画がスムーズに進み、各種表示が早まります。

103 Early HintsとHTTP/2 Server Pushの違い

HTTP/2には Server Push という仕組みがあり、サーバーからクライアントにリソースを「プッシュ」可能です。一見似たような発想に見えますが、Server Pushは「サーバーからクライアントに一方的にリソースを送る」のに対し、103 Early Hintsは「サーバーがクライアントにリソースの所在を教え、クライアントが自発的にフェッチする」点が異なります。

Server Pushは一時期注目を浴びましたが、実装やキャッシュの扱いに課題が多く、すでに廃止に向かっています。一方、103 Early Hintsは「Linkヘッダを先行通知するだけ」のシンプルな設計なため、段階的な普及やより広い利用が期待されます。

なぜ高速化につながるのか?

「サーバー待ち時間」の有効活用

サーバーが動的にHTMLを生成したり、データベース呼び出しをする間、ブラウザ側は何もできずに待っている時間が存在します。103 Early Hintsを導入することで、その時間を使ってリソースを fetch・先行読み込みすることが可能になります。

結果的に、ユーザーが感じるページ初期表示速度が向上し、 Largest Contentful Paint(LCP)などの CoreWebVitals などの重要指標の改善にもつながります。

フェッチパイプラインの前倒し

ブラウザに対して早期にリソース取得の指示を出すと、クライアント側でのリソースフェッチ早期に始動し、サーバー側は最終的なレスポンス送信を完了するまでの間にクライアントとの通信を並行して行えます。結果的に無駄な待機時間が削減され、全体のスループットが向上します。

103 Early Hintsのメリットとデメリット

メリット

  1. ページ表示の高速化
    ユーザー体験を左右する初期表示が速くなります。特に、スタイルシートやメインの画像・スクリプトなどを先読みできるのは効果的です。
  2. UXとSEOへの好影響
    ページ表示速度が上がると、直帰率の低下やユーザーエンゲージメントの向上が期待できます。また、速度指標は検索エンジンの評価にも影響するため、SEO効果も高まる可能性があります。
  3. 最新のCDNとの相性が良い
    Cloudflareなど、最新のCDNでは103 Early Hintsを活用した先読みの仕組みをサポートしており、CDNと連携することで世界中のユーザーに高速な体験を提供しやすくなります。
  4. 実装のコンセプトがシンプル
    HTTP/2 Server Pushと比べると、サーバー側やブラウザ側でのキャッシュ管理が相対的にシンプルです。Linkヘッダを送るだけで済むため、実装が容易です。

デメリット

  1. アプリケーションサーバー実装の負担
    アプリケーションサーバから 103 Early Hintsを返す場合は、アプリケーション側でレスポンスを2段階に分ける実装が必要です。フレームワークや言語によっては対応しているものもありますが、対応していないケースはまだかなり多いです。
  2. 通らないプロキシが多い
    昨今のWebアプリケーションはロードバランサやWAFなど、多段になったプロキシを経由することが多いですが、アプリケーションサーバからクライアントブラウザまで 103 レスポンスを通すためには経路の全てのサーバが対応している必要があります。これは現実的にはあまり期待できません。どちらかというとユーザに近いエッジサーバから 103 レスポンスを送出することを考えたほうがいいでしょう。
  3. 送るコンテンツの決定の難しさ
    どのページでも利用される共通の CSSスクリプトを指定するのは可能ですが、できればそれぞれのページの LCP 画像などを preload させた方が効果が期待できます。しかし、それを決定するためにはアプリケーションサーバが実際に処理をすすめないと分からないという循環に陥ります。
  4. 過剰なプリロードのリスク
    必要以上に大量のリソースをプリロードすると、かえってネットワーク混雑や無駄な帯域消費の原因になる場合もあります。適切なリソースの選定が重要です。

アプリケーションサーバでの実装例

以下のような方法で、アプリケーションサーバから直接 103 レスポンスを送ることができます。 上に書いたようにクライアントまで全てのリバースプロキシが対応している必要があるため、現実的には利用シーンは限定的かもしれません。

Ruby on Railsでの実装

Ruby on Rails(5.2以降)では、サーバに --early-hints オプションをつけて起動すると、簡単に 103 Early Hints を送ることができます。

元々 Rails では CSS や JS などのアセットを通常のリクエストで自動的に Link ヘッダに付けて返してくれる機能がありますが、これを更に Early Hints を利用しても送信します。

内部的には ActionDispatch::Request#send_early_hints メソッドが用意されており、これを呼び出しています。 サーバ側の対応も必要ですが、今は rack の API も正式なものになり、少なくとも puma, falcon, unicorn で利用できます。

Node.jsでの実装

Node.js 18.11 以降では、標準の http や http2 モジュールで、response.writeEarlyHints() というメソッドが利用可能です。

import { createServer } from 'http';

const server = createServer((req, res) => {
  // Early Hintsを送信
  res.writeEarlyHints({
    link: [
      '</style.css>; rel=preload; as=style',
      '</main.js>; rel=preload; as=script'
    ]
  });

  // 最終的なレスポンス
  res.writeHead(200, { 'Content-Type': 'text/html' });
  res.end(`
    <!DOCTYPE html>
    <html>
      <head>
        <link rel="stylesheet" href="/style.css">
      </head>
      <body>
        <script src="/main.js"></script>
      </body>
    </html>
  `);
});

server.listen(3000, () => {
  console.log('Server running at http://localhost:3000/');
});

この例では、/style.css と /main.js をプリロードし、本来のHTMLを200 OKで返しています。

その他

  • 通常の PHP は今のところ EarlyHints をサポートできず、 FrankenPHP を利用すれば可能です。
  • Java では JakartaEE (5.0.0-M1 以降) や Tomcat (11.0.0-M23) 以降で利用可能です。
  • どの言語でも Response あるいは Request オブジェクトに専用のメソッドが設けられているケースが多いです。

CDN プロバイダによる実装

103 Early Hints をアプリケーションサーバではなく、クライアントブラウザに近い CDN エッジから送信するという手もあります。

この場合、CDNは設定やキャッシュなどから送るべき内容を決定する必要があります。アプリケーションサーバと違い、preload する中身が今のコンテンツの実態と合わなくなってしまうリスクもありますが、中間に挟まるプロキシが少ないため、高い確率でクライアントブラウザまで到達することが期待できます。

Cloudflare

Cloudflare では、アプリケーションサーバが通常の 200 応答に Link ヘッダを付けて返すと、次のアクセスから透過的に 103 に変換してくれる、という便利な機能を持っています。

Fastly

Fastly では VCL を利用して Early Hints を送信できます。 中身は VCL を利用して自由にコントロールできますが、逆に言うと自分で送る内容を決定する仕組みを構築する必要があります。

実際の効果:数百ミリ秒の差が生む大きな違い

ネットワーク遅延が大きい環境や、ページ内で大量のスクリプトCSSを読み込むようなサイトでは、103 Early Hintsの効果が特に顕著です。 ページ読み込みの数百ミリ秒の違いは、ユーザー体験に大きく影響します。表示が遅くなるほど、ユーザーの離脱率が高まり、ECサイトであれば売上の減少にも直結します。また、通常は副作用が小さいため、採用するメリットは十分にあると言えるでしょう。

例えば、 Cloudflareでは LCP を 30%改善できたというレポートがあります。うまく活用できれば、高い効果が期待できそうです。

ただ一方、副作用が全くないわけではありません。 Shopify では効果はあるが、設定が難しい という話もありました。

今後の展望

  1. CDNとの連携強化
    すでにCloudflareなどの大手CDNが積極的にサポートを行っていますが、今後AkamaiAWS CloudFrontなど他のCDNプロバイダでも広範なサポートが期待されます。CDNを活用すれば、地理的に離れたユーザーにも高速な体験を提供できます。
  2. 各種プロキシの対応拡充
    現状リバースプロキシは 1xx のステータスを通してくれるものは多くありません。各クラウドプロバイダのリバースプロキシが対応してくれると嬉しいところです。そうしてくれれば、かなり構成の自由度が増えます。
  3. 送るべきコンテンツの決定選択肢の増加
    Early Hints で送るべき情報をどのように集め決定するかに関しては、まだまだ様々なアプローチが考えられます。実ユーザからの情報を集めて自動的に送信内容を決定するなど、より効果的な仕組みの選択肢が増えることを期待しています。

まとめ

103 Early Hints は、サーバーが最終レスポンスを送る前に、クライアントへプリロードすべきリソースを通知することで、ウェブページの表示速度を改善できる可能性のあるHTTPステータスコードです。各種サーバーやミドルウェアの対応状況などの課題はあるものの、現時点でも使い始められる仕組みは整備され始めており、CloudflareなどのCDNも積極的にサポートしています。

数百ミリ秒の高速化でもユーザー体験や売上、ブランドイメージに大きく貢献する可能性があり、うまく使いこなせれば1つ抜きん出たパフォーマンスを発揮できる可能性があります。ぜひ検討してみてください。

Repro Booster ではこのような Web パフォーマンスに関する技術の調査や検証を行い、プロダクトに活かせるものは積極的に採用しています。

また、このような Web パフォーマンスに興味があり、一緒に働ける開発者の方を募集しています。もし興味があれば、ぜひ気軽にご連絡ください。

Note

(Blog全体ではなく) この記事本文及び記事中に利用されている画像・図表は CC 4.0 BY-SA でライセンスされており、自由に利用できます。




以上の内容はhttps://tech.repro.io/entry/2025/01/28/125334より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14