🦉

プリフェッチとは何かについて考える

に公開

プリフェッチとは、次に必要になりそうなリソースをブラウザが「空いているときに」「低優先度で」先読みし、HTTP キャッシュなどに置いておく仕組み。ユーザーがそのリソースを本当に要求したときの待ち時間を短くするのが目的。省電力・帯域節約のため、ブラウザは状況によってプリフェッチをスキップすることがある(必ず走るわけではない)。

HTML の Link type の一種として定義される。Link type とは、<link>(や<a>など)に書くrel属性の値を分類した概念で、リンクの意
味やブラウザ処理の優先度を示すラベルのこと。Resource Hints仕様は W3C Working Draft(勧告ではない)段階で、prefetchのほ
かにpreloadpreconnectdns-prefetchprerender など、ブラウザに「どのリソースをどの優先度で扱うか」を伝えるヒントが
揃っている。Link type はrel属性で指定し、ブラウザが解釈する手がかりになる。

補足:ブラウザが「空いているとき」とは?
画面描画やユーザー入力処理、既存リソースのダウンロードが落ち着いているタイミングのこと。高優先度の処理(今の表示に必要な CSS/JS/画像の取得やユーザー入力応答など)を優先し、余力があるときだけ低優先度のプリフェッチを走らせる。

アイドル状態とは? 画面描画やユーザー入力処理、優先度の高いネットワークリクエストが一段落し、メインスレッドやネットワークキュー
に空きがある状態。ブラウザはこのタイミングで低優先度のプリフェッチを走らせる。

プリフェッチの動作フロー

プリフェッチと近い概念との違い

今回の主役はあくまでプリフェッチではあるが、他にも pre 何ちゃらで見かけるものがあるので、以下にまとめた。個人的に使用するものといえば、Web フォント読み込み設計をする際に preload 使う時あるかもなぁのレベルの為、今後色々使用してみたい。

突っ込みがあれば、ぜひ色々教えていただきたい。。。

種類 優先度 説明
prefetch 先読みするが実際に使われるかは未確定。主に「次のページ・次に使う可能性が高い静的リソース」向け
preload ほぼ確実に使うリソースを即座に取得する。現在のページの表示に必要なもの向け(CSS・フォント・画像など)
prerender / speculationrules - 次ページを丸ごと描画まで先行実行する。ヒットすると遷移がほぼ瞬時。コストが大きいので対象は絞る
preconnect / dns-prefetch - DNS 解決や TCP/TLS ハンドシェイクだけ先にやる。リソース本体は取得しない

いつ使うと効果的か

プリフェッチも目的は、ユーザーがそのリソースを本当に要求したときの待ち時間を短くしすること、言い換えれば待ち時間を短くしユーザー体験を良くすることにある。しかし、どんな場面でもプリフェッチを乱発すればいいわけではなく、次のような場面での使用が良さそう。

  • 次に移動しそうなページが高い確率でわかるとき(例: 記事一覧 → 最上位にある記事詳細)。
  • 画像ギャラリーやページネーションで「次へ」「前へ」が踏まれやすいとき。
  • SPA でも「次に遷移しそうなルート」のスクリプトやデータフェッチを前倒ししたいとき。
  • EC サイトの商品一覧ページで、最も人気のある商品の詳細ページを先読み。
  • ログインページで、ログイン後に表示されるダッシュボードのリソースを先読み。
  • ウィザード形式のフォームで、次のステップのコンポーネントを先読み。

ポイント:導線がシンプルなほど効果的なプリフェッチを設計しやすい
次に行く先が予測しやすいシンプルな導線(一覧 → 詳細、「次へ」「前へ」)ほど当たりやすい。多岐分岐する複雑な UI では命中率が落ちるので対象を絞る。

後述するキャッシュと合わせて設計しないと、API のリクエスト回数が増える可能性があり、API を提供するサーバーの負担が増加する可能性が高い。

使い方(HTML Resource Hints)

補足:rel 属性とは?
HTML リンクタイプを示す属性。<link rel="prefetch" ...> のように書いて、ブラウザに「これは先読みのヒントだよ」と伝えるためのラベル。

<!-- 次ページを先読み(documentとして扱う) -->
<link rel="prefetch" href="/articles/next" as="document" />

<!-- JSチャンクを低優先度で先読み -->
<link
  rel="prefetch"
  href="/static/chunk.abc123.js"
  as="script"
  crossorigin="anonymous"
/>

as 属性について

先読みするリソースの種類をブラウザに伝える属性。正しく設定すると適切な優先度や CORS 処理・キャッシュキーになる。省略するとブラウザは一般的なフェッチとして扱い、実際のレスポンスヘッダを見て後から種類を推測するため、優先度やキャッシュキーが最適にならない場合がある。多くのフレームワーク(例: ルーティング時に自動プリフェッチするもの)は、リンク先が HTML か JS かなどのメタ情報を元にasを自動付与する実装が多い。

用途
as="document" HTML ドキュメント
as="script" JavaScript ファイル
as="style" CSS ファイル
as="image" 画像ファイル
  • クロスオリジンの場合は crossorigin を合わせて指定する。

HTTP キャッシュとの関係

プリフェッチ結果は通常の HTTP キャッシュに格納される。HTTP キャッシュとは、ブラウザがリソースをローカル(ディスクやメモリ)に保存して再利用する仕組みのこと。Cache-ControlETag などのヘッダで有効期限や再検証を制御する。

Cache-ControlETag はレスポンスヘッダとしてサーバー側で設定する。静的ホスティング(例: Vercel/Netlify/S3+CloudFront)ではビルド成果物に対するキャッシュポリシーを設定ファイルや管理画面で指定し、SSR/SPA ならアプリケーションサーバーや CDN 設定でヘッダを付与する。Cache-Control を適切に設定しておくことで、プリフェッチの効果を最大化できる。

運用時の注意

大きなリソースの扱い

大きなリソース(動画・高解像度画像・巨大 JS バンドルなど)を無差別にプリフェッチすると帯域/バッテリを消費する。クリック確率が高いものだけに絞る。

ブラウザによるスキップ

ユーザーの回線状況やデバイスによってブラウザがプリフェッチをスキップすることがある。「動く前提」にしない。

認証が必要なリソース

ログイン済みユーザーだけが取れる API レスポンスやマイページの HTML/JSON、クッキー付き静的ファイルなどをプリフェッチする場合、認証クッキーが送られるので不要なセッション消費や意図しないトラッキングにならないか確認する。

キャッシュ戦略との連携

先読みしてもキャッシュの有効期限が切れれば再取得になる。キャッシュ戦略とセットで考える。

補足:stale-while-revalidate とは?
HTTP キャッシュディレクティブ(レスポンスヘッダ)で、キャッシュが多少古くても即返しつつ裏で再検証させる挙動を指示する。ブラウザや CDN が対応しており、API でも静的ファイルでも利用できる。

Web API リソースの過度なプリフェッチ

Web API で動的に取得するリソースを過度にプリフェッチすると、API を提供するサーバーに高い負荷がかかる。特にユーザーごとにパーソナライズされたデータや、リアルタイム性が求められるデータは、プリフェッチの対象から外すか、頻度を制限することを検討する。

動作確認のしかた

いろんな見方がありますが、Chrome であれば、Devtools > Elements で prefetch と検索すれば見つけることができます。以下は Zenn の TOP ページで確認できたものです。今回の場合は、Next.js の ビルド時に生成される code-splitting chunk を先読みしているかと思われます。

zenn prefetch

そのほかの見方としては、同じく Chrome > Devtools > Network でprefetch と検索したりすると見つけることができます。通信モードを 「No throttling」に切り替えたりすることで、prefetch の機能の有無を確認することも可能かなと思います。

まとめ

今回はプリフェッチについて触れてきました。まとめは以下になります。

  • プリフェッチは「次に使いそうなものを、今の描画を邪魔しない範囲で先に取っておく」仕組み。
  • とりあえずのプリフェッチはなるべく避ける。
  • 効果はユーザー行動の予測精度に依存する。対象を絞り、計測しながら運用する。

個人的にフレームワークを通してプリフェッチをなんとなく使用したりすることが多かったため、今後はより良い設計をしつつ使用の有無を考えていければと思います。

また、プリフェッチの有無やそれによるパフォーマンスをものすごく手軽に感じれるサンドボックスやサイトを知っていらっしゃる方がいればぜひシェア頂ければとても嬉しいです。

本記事を読んでいただきありがとうございました!

参考 URL(公式・支持が厚い資料)

Discussion