103 Early Hintsで静的ファイル用のURLをpreconecctしてみた
https://sizu.me ではCSSやJSなどの静的ファイルをstatic.sizu.me
から読み込んでいる。しかしブラウザがsizu.me
から返されたHTMLを読んでからstatic.sizu.me
へのDNS Lookupなどを始めるのは効率が悪い。
そこで103 Early Hintsによりstatic.sizu.me
へのpreconnectがなる早で開始されるようにできないか試してみた。
ちなみに2023/11/25時点では、103 Early Hintsに一部のブラウザが対応していないことに注意(caniuse)。未対応のブラウザ向けにはheadのなるべく上にpreconnect用のlinkを配置しておく。
<link rel="preconnect" href="https://example.com" />
sizu.meでは静的ファイル以外のリクエストについてはCloudflare Workersでプロキシしている。そこで、Workersに以下のようなコードを追加した。
const response = await fetch(url.toString(), request);
// ...略...
// HTMLのレスポンスには静的ファイル用のURLをLinkヘッダで付与することで、103 Early Hintsによるpreconnectを促す
if (response.headers.get("content-type")?.includes("text/html")) {
response.headers.append(
"link",
`https://static.sizu.me; rel=preconnect;`
);
}
Cloudflareでは設定でEarly HintsをONにするとオリジンからのレスポンスヘッダに含まれるlinkタグの内容に応じて103レスポンスを先に返してくれるようになる。詳しくは下記の記事を参照。
Chromeのnetworkタブでは103リクエストが表示されないので、curlでリクエストしてみる。以下のようにステータスコード103のレスポンスが先に返ってきていることが分かる。
ChromeでDNSのキャッシュがない状態でリクエストしてみる。以下サイトを表示したときに一番最初に読み込まれるstatic.sizu.me
の静的ファイルのレスポンスに関するもの。
103 Early Hintsなし
103 Early Hintsあり
DNS Lookupなどの表示がなくなった。Stalled(ファイルへのリクエストまでの待ち時間)が長くなったのは、早めに実行されたpreconnectが完了するまでの時間がここに含まれているからなのかな?
読み込みごとにdurationのバラツキがあるので、どれだけ表示速度に効いているのか微妙なところだが、しばらくこれで運用してみる。
これは個人的な疑問なのだが、Cloudflareではオリジンからのレスポンスを受け取ってからそのレスポンスヘッダ内に含まれるLink
確認し、103レスポンスを返すかどうか決める仕様となっている。
つまりオリジンからのレスポンスを受け取るまでは103レスポンスが返すことができないことになる(それともキャッシュして、いち早く返してるのかな?)。オリジンからのレスポンスを受け取る前に103レスポンスを返せたらもっと効果が出そうな気がする。
2回目以降(cloudflareがcacheを持っている場合)はcacheを返しているように読めます。
「HTTP Status Code 103 Early Hintsを試す」の参照先のブログにある「Now: Turning 200 OK Link: headers into 103 Early Hints」を見た感じ。
ほんとだ!情報ありがとうございます!