TL

ブラウザのプリレンダリングと投機的ナビゲーション(Speculation Rules)

リンクを踏む前にページを丸ごと用意しておき、クリックの瞬間に即表示する。Speculation Rules による prerender/prefetch の指定、プリレンダ中のスクリプト制限とアクティベーション時の挙動を内部から正確に解きます。

応用プリレンダリングブラウザパフォーマンスナビゲーションCore Web Vitals最終更新: 2026-06-21
TL;DR要点だけ先に
  • 1.Speculation Rules API は JSON で「どのURLを prefetch / prerender するか」を宣言する。prefetch はレスポンス本文の先行取得まで、prerender は非表示タブで DOM 構築・スクリプト実行まで済ませて凍結し、遷移時にそれを前面へ昇格(アクティベーション)するため、表示は実質ゼロ往復で完了する。
  • 2.プリレンダ中のページは prerendering 状態に置かれ、document.prerendering が true になる。アクティベーション前はダイアログ・権限要求・自動再生・一部の保存系 API などが遅延または抑止され、副作用を伴う処理は prerenderingchange まで待つ必要がある。
  • 3.アクティベーション時、ロードは再実行されない。代わりに prerenderingchange が発火し、Navigation Timing の activationStart 以降が「見えた後」の時間になる。遅延していた処理はここで解放され、計測も activationStart を基準に補正する。

投機的ナビゲーションとは何か:遷移を先回りする

ユーザーがリンクをクリックしてから次のページが表示されるまでには、本来「URL解決→リクエスト→レスポンス受信→HTMLパース→サブリソース取得→描画」という一連のコストがかかります。投機的ナビゲーション(speculative navigation) は、ユーザーが次にどこへ行くかをあらかじめ推測し、このコストをクリック前に先払いしておく技術です。うまく当たれば、クリックの瞬間に残っているのは「用意済みのものを前面に出す」操作だけになり、体感は即時に近づきます。

この先払いには段階があります。軽い順に prefetch(先行取得)prerender(プリレンダ) の2つで、どこまで先払いするかが違います。

手段やること完了時点の状態コスト
prefetch対象URLのレスポンス本文までを先行取得しキャッシュバイト列は手元にあるがDOMは未構築低(ネットワークのみ)
prerender非表示で完全にページを描画し凍結DOM構築・スクリプト実行まで完了済み高(CPU・メモリも消費)

prefetch は遷移時にネットワーク往復を省きますが、パースと描画はクリック後に行われます。prerender はパースと描画まで済ませて待機させるため、遷移時はほぼ表示だけで済みます。代わりに当たらなかったときの無駄(取得したデータ・消費したCPUとメモリ)が大きいので、確度に応じて使い分けるのが原則です。

Speculation Rules API:宣言的に投機を指定する

かつての <link rel="prefetch"> や非標準の <link rel="prerender"> は、URLを1つずつ静的に書くしかなく、条件や確度を表現できませんでした。Speculation Rules API はこれを置き換えるもので、<script type="speculationrules">JSON を書いて「どのURL群を、どの手段で、どの確度(eagerness)で投機するか」を宣言します。

<script type="speculationrules">
{
  "prerender": [
    {
      "where": { "href_matches": "/articles/*" },
      "eagerness": "moderate"
    }
  ],
  "prefetch": [
    {
      "where": { "selector_matches": ".nav-link" },
      "eagerness": "conservative"
    }
  ]
}
</script>

where で対象URLを指定します。href_matches はURLパターン、selector_matches はそのセレクタに一致するリンク(href)を対象にする、という具合です。urls で明示列挙もできます。ここで重要なのが eagerness(積極度) で、ブラウザがいつ投機を始めるかを制御します。

eagerness発火の目安想定用途
immediateルール評価時に即実行次に行くのがほぼ確実なURL
eagerごく早い段階(リンクが視野に入る頃)確度の高い遷移先
moderateホバーや一定時間の指差し(200ms程度)でクリックされそうなリンク
conservativeポインタダウン(押し込み)で誤爆を避けたい場面

conservative はクリック直前(ボタンを押し込んだ瞬間)に投機するため無駄が最小ですが、先払いできる時間も最短です。immediate は確実ですが外れたときの浪費が最大になります。ブラウザはこの宣言をヒントとして受け取り、回線状況・メモリ・省データ設定・同時投機数の上限などを見て、実際に投機するかを最終判断します。宣言は強制ではない点が肝心です。

同一サイト prerender と across-site prefetch

prerender は基本的に**同一オリジン(same-origin)**が対象で、同一サイトの別オリジンを丸ごと裏で描画するには遷移先サーバーが Supports-Loading-Mode ヘッダで明示的にオプトインする必要があり、別サイト(cross-site)の prerender はそもそも許可されません。一方 prefetch はクロスサイトにも使えますが、その場合は参照元を秘匿するためプライバシー保護プロキシ経由になり、Cookie を伴わない匿名取得になります。スクリプトまで実行する「丸ごと描画」の prerender ほど適用範囲が狭い、と覚えると整理できます。

プリレンダ中の状態:見えていないページの制約

prerender されたページは、ユーザーには見えない非表示の別タブのような環境で構築されます。この間ページは prerendering 状態 に置かれ、document.prerenderingtrue になります。問題は、まだ誰も見ていない・操作していないページが、勝手に副作用を起こしてはいけない点です。そこでブラウザはプリレンダ中の挙動に多くの制約を課します。

カテゴリプリレンダ中の扱い理由
ダイアログ(alert / confirm)抑止または無視見えないページがユーザー操作を奪えない
権限要求(カメラ・通知・位置)自動拒否または保留ユーザーの明示的来訪なしに許可を問えない
メディアの自動再生ブロック見えないページから音や動画を流さない
window のサイズ・可視性 API非可視として報告実際に表示されていないため
一部のストレージ・通信副作用遅延される場合がある未確定の遷移で状態を書き換えないため

ここで実務上の落とし穴になるのが アクセス解析や広告のビーコン です。プリレンダ段階でページビューを送ってしまうと、実際にはユーザーが来ていない(外れた投機の)ぶんまで計上され、水増しが起こります。これを避けるため、計測タグはプリレンダ中に発火させず、アクティベーション後に送る設計にする必要があります。多くの解析ライブラリは document.prerendering を見て自動で遅延しますが、自作のビーコンは自分で制御しなければなりません。

プリレンダ中に副作用を起こさない

プリレンダされたページのスクリプトは、DOM構築やデータ取得といった準備は進めてよい一方、ユーザーの来訪を前提にした副作用——ページビュー送信、購入や投票のような状態変更、フォーカスを奪う UI、通知の発行——は行ってはいけません。これらは「実際に表示された後」に回します。判定は document.prerendering で、true の間は副作用を保留する分岐を入れます。

アクティベーション:凍結を前面へ昇格する瞬間

ユーザーが実際にそのURLへ遷移すると、ブラウザは裏で用意したプリレンダ済みドキュメントを前面に昇格させます。これを アクティベーション(activation) と呼びます。ここで決定的に重要なのは、ページのロードがやり直されないことです。HTML の再取得も、再パースも、スクリプトの再実行もありません。すでに生きているドキュメントが、そのまま「見えるタブ」になります。

この設計のため、初回ロード前提のフックだけでは「表示された瞬間」を捉えられません。アクティベーションを検知する専用のシグナルが用意されています。

if (document.prerendering) {
  // まだ非表示。準備だけ進め、副作用は保留する
  document.addEventListener('prerenderingchange', onActivated, { once: true });
} else {
  // 通常ロード、またはすでにアクティベート済み
  onActivated();
}

function onActivated() {
  // 「ユーザーに見えた」後にだけやるべきこと
  sendPageView();          // 計測ビーコンはここで
  startAutoplayIfNeeded(); // メディア再生もここで
  focusSearchBox();        // フォーカス移動もここで
}

prerenderingchange イベントは、prerendering 状態が解けた(=アクティベートされた)瞬間に document 上で発火します。document.prerendering はこの時点で false になります。プリレンダ中に保留していた副作用は、すべてこのフックの先で解放するのが定石です。

activationStart で計測を補正する

Navigation Timing には activationStart という値が加わります。これは「ナビゲーション開始からアクティベーションまで」の時間で、プリレンダで先払いした準備時間に相当します。プリレンダが効いたページでは、startTime ではなく activationStart を起点に各種タイミングを引き直すことで、「ユーザーに見えてから」の真の表示時間が求められます。FCP や Core Web Vitals の LCP も、アクティベーション基準で測ると実態に合った値になります。

bfcache・プリロードスキャナとの違い

似た「速くする仕組み」と混同しないことが大切です。プリレンダは遷移前に未来のページを新規構築するのに対し、bfcache(Back/Forward Cache)過去に訪れたページの生きた状態を凍結して戻る/進むで復元します。前者は前向き(これから行く先)、後者は後ろ向き(来た道)の最適化で、復元時のイベントも異なります(プリレンダは prerenderingchange、bfcache は pageshowevent.persisted)。

また prefetch/prerender は「ページ単位で次の遷移先を丸ごと先払いする」のに対し、プリロードスキャナ は「現在のページの中で、これから要るサブリソースを先に取得する」仕組みです。スコープが「次のページ全体」か「今のページの部品」かで層が違います。

仕組み対象向き復元/表示のフック
prerender次の遷移先のページ全体前向き(未来)prerenderingchange
prefetch次の遷移先のレスポンス本文前向き(未来)通常ロード(取得だけ前倒し)
bfcache過去に訪れたページの状態後ろ向き(履歴)pageshow(persisted)
プリロードスキャナ現在ページのサブリソース現在ページ内—(取得の前倒しのみ)
プリレンダは状態を持ち込む——認証と整合に注意

プリレンダ済みページは「少し前の時点」で構築されています。構築からアクティベーションまでに時間が空くと、表示される内容が古くなり得ます。認証トークンの失効、在庫やカートの変化、相対時刻(「○分前」)などは、prerenderingchange で再検証・再取得するのが安全です。とくにログイン状態に依存する画面は、プリレンダ時と来訪時でユーザーが変わっている可能性まで考え、アクティベーション時にサーバー状態を確認してください。

セキュリティ・運用上の注意

プリレンダはサーバーから見ると「ユーザーがまだ来ていないのにリクエストが飛んでくる」状況を生みます。Sec-Purpose: prefetch のようなリクエストヘッダでブラウザが投機リクエストであることを示すため、サーバー側は副作用のある GET を投機で叩かれても安全かを点検し、必要なら投機リクエストを識別して扱いを変えられます(破壊的操作を GET に載せない原則がここでも効きます)。

クロスサイト prefetch がプロキシ経由・Cookie なしで行われることも運用上の前提です。ログイン依存のコンテンツはこの匿名取得では正しく取れないため、prerender(same-site・通常の資格情報あり)と prefetch(cross-site・匿名)で取得結果が変わることを理解しておきます。コンテンツの取り扱いは CSP(Content Security Policy) とも関係し、プリレンダされる側のページも自身の CSP に従って評価されます。

試験・面接の頻出ポイント

押さえどころは5つです。❶ prefetch は本文取得まで、prerender は DOM 構築・スクリプト実行まで先払いし非表示で凍結する。❷ Speculation Rules は <script type="speculationrules"> の JSON で対象(href_matches / selector_matches)と eagerness(immediate / eager / moderate / conservative)を宣言するヒントである。❸ プリレンダ中は document.prerendering === true で、ダイアログ・権限・自動再生・計測ビーコンなどの副作用を抑止/遅延する。❹ アクティベーションでロードは再実行されず、prerenderingchange が発火し副作用を解放する。❺ 計測は activationStart を起点に補正する。

まとめ

まとめ

投機的ナビゲーションは、次の遷移先を推測してクリック前にコストを先払いする最適化です。prefetch はレスポンス本文の先行取得まで、prerender は非表示タブでの DOM 構築・スクリプト実行まで進めて凍結し、遷移時にアクティベーションでそれを前面へ昇格させるため、表示は実質ゼロ往復になります。指定は Speculation Rules API<script type="speculationrules"> の JSON)で行い、対象URLと eagerness をヒントとして宣言します。プリレンダ中のページは document.prerendering === true の制約下にあり、ダイアログ・権限・自動再生・計測ビーコンなどの副作用は抑止/遅延し、prerenderingchange 後に解放します。アクティベーションでロードは再実行されないため、タイミングは activationStart を基準に補正します。過去のページを凍結する bfcache、現在ページの部品を前倒しする プリロードスキャナ と層を分けて捉え、認証や鮮度の整合はアクティベーション時に再検証すれば、安全に「即表示」を Core Web Vitals ごと引き上げられます。

Web/フロントエンド Article

ブラウザのプリレンダリングと投機的ナビゲーション(Speculation Rules)を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

プリレンダリング

比較で見る軸

難易度: advanced / カテゴリ: Web/フロントエンド / タグ数: 5

導入後に効く点

プリレンダ中のページは prerendering 状態に置かれ、document.prerendering が true になる。アクティベーション前はダイアログ・権限要求・自動再生・一部の保存系 API などが遅延または抑止され、副作用を伴う処理は prerenderingchange まで待つ必要がある。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
Web/フロントエンド
タグ数
5

判断チェックリスト

  • 自社の用途が「プリレンダリング / ブラウザ」に近いか確認する。
  • 強みである「Speculation Rules API は JSON で「どのURLを prefetch / prerender するか」を宣言する。prefetch はレスポンス本文の先行取得まで、prerender は非表示タブで DOM 構築・スクリプト実行まで済ませて凍結し、遷移時にそれを前面へ昇格(アクティベーション)するため、表示は実質ゼロ往復で完了する。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

プリレンダリングブラウザパフォーマンスナビゲーションCore Web Vitalsプリレンダリングブラウザパフォーマンス
参考: 公式情報