Speculation Rules API 完全ガイド|prefetch・prerender・Chrome 144 prerender_until_script
Speculation Rules APIは、次に遷移される可能性が高いページを prefetch(先読み)または prerender(先描画)して、クリック後の体感を大きく短縮する標準APIだ。
document rules + eagernessで「どのリンクを・いつ投機するか」を宣言的に制御できる。- Chrome 144(2026年)では
prerender_until_script(Origin Trial)が追加され、JS副作用を抑えつつ サブリソース先読みを進められる。 - 実運用は conservative prefetch → moderate prerender(または prerender_until_script) の段階導入が安全。
Speculation Rules API とは
Speculation Rules API(投機ルールAPI)は、ブラウザが将来のナビゲーションを事前に開始し、クリック後の表示を高速化するためのWeb標準だ。ルールは <script type="speculationrules"> 内のJSONで宣言し、対象URL・投機タイプ(prefetch / prerender / prerender_until_script)・発火タイミング(eagerness)を指定する。
従来の <link rel="prefetch"> は1URL・1リソース種別に限定され、ホバー検知や複数条件の組み合わせはJavaScriptで自前実装が必要だった。Speculation Rules APIは list source(URLリスト)と document source(ページ内リンクから自動抽出)の2モードを持ち、Chrome 122以降で eagerness により「いつ投機するか」をブラウザ標準のヒューリスティックに委ねられる。
ナビゲーション性能の改善は、クリティカルレンダリングパス最適化が「現在のページ」のFCP・LCPを短縮するのに対し、Speculation Rulesは次のページのTTFB・LCPを短縮する。両方を組み合わせると、初回訪問はCRP最適化、サイト内回遊は投機ルール——という二層構造のパフォーマンス戦略が成立する。
従来手法との対応関係
| 従来 | Speculation Rules API | 備考 |
|---|---|---|
<link rel="prefetch" href="..."> | "prefetch": [{ "urls": ["..."] }] | 複数URL・条件付きが可能 |
<link rel="prerender" href="..."> | "prerender": [{ ... }] | link版prerenderは非推奨 |
| JS hover prefetch | "eagerness": "moderate" | 200msホバーはブラウザ標準 |
| 自前Intersection Observer | "eagerness": "conservative" + viewport heuristics | モバイルはpointerdownベース |
Speculation Rules APIの prefetch はChrome 121+、Edge 121+で安定利用可能。prerender はChrome 109+(段階的改善)。document rules と eagerness はChrome 124+。prerender_until_script はChrome 144+ Origin Trial(2026年1月〜)。Firefox・Safariはprefetch相当の部分実装にとどまるため、同一JSON内にprefetchフォールバックを併記するのが定石だ。
prefetch と prerender の根本的な違い
投機ルールの中核は prefetch(先読み) と prerender(先描画) の2アクションだ。どちらも「ユーザーがまだクリックしていないURL」を対象にするが、ブラウザ内部で行われる処理量が桁違いに異なる。
prefetch が行うこと
prefetchは主に HTMLドキュメントをネットワーク層で先取得 する。ブラウザはHTTPキャッシュ(またはメモリキャッシュ)にレスポンスを格納するが、HTMLパース・CSSOM構築・JS実行・ペイントは行わない。ユーザーが実際にナビゲーションした時点で、キャッシュヒットすればTTFBが短縮される。
prefetchの利点は 副作用が小さい ことだ。JSは走らないため、Google Analyticsのpageview二重計数や、認証トークンの意図しない更新は起きにくい。欠点は、サブリソース(CSS・JS・フォント・LCP画像)がまだ取得されていないため、クリック後もCRPの大半はこれから という点だ。
prerender が行うこと
prerenderは 非表示の独立したBrowsing Context でページ全体を読み込む。HTMLパース、CSSOM/DOM構築、JavaScript実行、レイアウト、ペイントまで完了する。ユーザーがリンクをクリックすると、prerender済みページが アクティベーション され、体感上「瞬時に」表示される。
prerenderは HTTP/2・HTTP/3の接続再利用 と組み合わさると、先読みフェーズでTCP/QUIC接続・TLS・DNSが済んでいるため、クリック後のネットワーク待ちがほぼゼロになるケースもある。ただし メモリ(数十MB/ページ) と CPU(JS実行・レイアウト) のコスト、および JS副作用 が最大のリスクだ。
| 観点 | prefetch / prerender |
|---|---|
| HTML取得 | 両方とも実施 |
| サブリソース取得 | prefetch: 限定的 / prerender: preload scannerで積極的 |
| DOM・CSSOM構築 | prefetch: なし / prerender: あり |
| JavaScript実行 | prefetch: なし / prerender: あり(副作用リスク) |
| First Paint | prefetch: なし / prerender: 非表示コンテキストで完了 |
| クリック後の体感 | prefetch: TTFB短縮 / prerender: ほぼ即時表示 |
| リソース消費 | prefetch: 低 / prerender: 高(メモリ・CPU・帯域) |
数値感:click-to-LCP の改善イメージ
同一ブログ記事(HTML 45KB、CSS 80KB、JS 120KB、LCP画像 200KB)への内部リンク遷移をWebPageTestで計測した場合の典型値だ(4G、RTT 80ms環境の参考値)。
prerender moderateで click-to-LCPが2秒以上短縮 されることは珍しくない。prefetchだけではサブリソース待ちが残るため、改善幅は500〜800ms程度にとどまることが多い。Chrome 144の prerender_until_script は、JS実行前にサブリソース先読みまで進めるため、prefetchとprerenderの中間値(600ms前後)に収まるケースが報告されている。
Chrome 144:prerender_until_script
2026年1月リリースの Chrome 144 から、Speculation Rules APIに第3のアクション prerender_until_script がOrigin Trial(Chrome 144〜150)で追加された。WICG nav-speculation仕様に基づく「中間層」であり、prefetchの低コストとprerenderの表示速度のバランスを取る設計だ。
動作の詳細
prerender_until_script は次の順序で処理を進める。
- HTMLドキュメントを取得(prefetchと同様)
- HTMLパーサーを開始し、DOM構築とpreload scannerによるサブリソース発見を実行
- CSS・画像・フォントなど 非スクリプトリソース を先読み
- 最初のブロッキング
<script>タグ(inline / external 両方)に到達した時点でパーサーを一時停止 - JS実行・タイマー・Promise解決はすべて アクティベーションまで保留
- ユーザーが実際にナビゲーションした瞬間、スクリプト実行を再開し通常ロードを完了
つまり React/Vue/Next.jsのバンドルJSが実行される前 に、CSSとLCP画像がキャッシュに載る。フルprerenderほどAnalyticsや認証ロジックが動かないため、副作用リスクを大幅に抑えられる。
prefetch フォールバック付き実装例
Origin Trial中の機能は、未対応ブラウザではJSONキーが無視される。同一条件でprefetchを併記し、Chromeが利用可能な最強アクションを自動選択させる。
<script type="speculationrules">
{
"prerender_until_script": [
{
"source": "document",
"where": {
"and": [
{ "href_matches": "/blog/*" },
{ "not": { "href_matches": "/blog/*/edit" } },
{ "not": { "selector_matches": ".no-prerender" } }
]
},
"eagerness": "moderate",
"referrer_policy": "strict-origin-when-cross-origin"
}
],
"prefetch": [
{
"source": "document",
"where": {
"and": [
{ "href_matches": "/blog/*" },
{ "not": { "href_matches": "/blog/*/edit" } },
{ "not": { "selector_matches": ".no-prerender" } }
]
},
"eagerness": "moderate",
"referrer_policy": "strict-origin-when-cross-origin"
}
]
}
</script>
Origin Trialトークンは <meta http-equiv="origin-trial" content="TOKEN"> またはHTTPヘッダー Origin-Trial: TOKEN で有効化する。ローカル検証は chrome://flags/#prerender-until-script でも可能だ。
prerender_until_script は2026年6月時点で Intent to Ship未提出 の実験機能だ。本番トラフィックの一定割合でのみ有効化し、RUMで帯域・メモリ・Conversionへの影響を計測すること。仕様変更やTrial終了(Chrome 150頃)に備え、prefetchフォールバックは削除しない。
eagerness:いつ投機を開始するか
eagerness は「どのURLを投機するか」(where条件)と独立した、発火タイミング の設定だ。Chrome 124以降、list rules と document rules の両方で利用できる。
| eagerness | 発火条件 | list rules デフォルト | document rules デフォルト |
|---|---|---|---|
immediate | ルール解析直後 | immediate | — |
eager | 現状はimmediateと同等(将来は中間値予定) | — | — |
moderate | 200msホバー、またはpointerdown(モバイル) | — | — |
conservative | pointerdown / touchstart | — | conservative |
document rulesのデフォルトが conservative なのは、1ページに数十〜数百の <a> がある場合、immediate 指定で全リンクを即座にprerenderすると帯域とメモリが爆発するためだ。
Chrome の同時実行上限
Chromeはeagernessごとに投機数の上限を設けている(2026年6月時点)。
| eagerness | prefetch 上限 | prerender 上限 |
|---|---|---|
immediate / eager | 50 | 10 |
moderate / conservative | 2(FIFO) | 2(FIFO) |
moderate/conservativeは 同時2件まで で、古い投機はFIFOで破棄される。ブログ一覧で50記事リンクがあっても、ホバー中の1〜2件だけが対象になるため、意図しない大量先読みは起きにくい。
推奨戦略:段階的エイジャーシー
Phase 1: document rules + conservative + prefetch のみ(副作用ゼロで帯域影響を確認)
Phase 2: 高CTRページ(トップ5記事)に list rules + immediate prefetch を追加
Phase 3: 同一オリジン記事リンクに moderate + prerender_until_script(Chrome 144+)
Phase 4: 計測で問題なければ moderate + prerender に限定アップグレード
Phase 5: RUMでprerenderヒット率・bounce率・Conversionを2週間モニタリング
immediate prefetch + moderate prerender の組み合わせは、Chrome Developers公式ガイドでも推奨される定番パターンだ。ページロード時に人気記事3本をprefetchし、ユーザーがリンクにホバーした時点ではHTMLキャッシュ済みのため、prerenderがサブリソースと描画に集中できる。
<script type="speculationrules">
{
"prefetch": [
{
"urls": [
"/blog/critical-rendering-path-最適化/",
"/blog/http2-http3-違い-パフォーマンス比較/",
"/blog/speculation-rules-api-prefetch-prerender/"
],
"eagerness": "immediate"
}
],
"prerender": [
{
"source": "document",
"where": {
"and": [
{ "href_matches": "/blog/*" },
{ "not": { "href_matches": "/admin/*" } }
]
},
"eagerness": "moderate"
}
]
}
</script>
document rules:ページ内リンクから自動抽出
document source は、現在のHTMLドキュメント内の <a href> から条件に合致するURLを自動的に投機対象にする。list sourceでURLを手動列挙する方式より、CMSで記事が増えてもメンテナンス不要という利点がある。
where 条件の書き方
where オブジェクトは href_matches(URLパターン)、selector_matches(CSSセレクタ)、and / or / not の論理演算を組み合わせられる。
<script type="speculationrules">
{
"prefetch": [
{
"source": "document",
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "/logout" } },
{ "not": { "href_matches": "/cart" } },
{ "not": { "href_matches": "/checkout/*" } },
{ "not": { "selector_matches": "[download]" } },
{ "not": { "selector_matches": "[target=_blank]" } },
{ "not": { "selector_matches": ".external-link" } }
]
},
"eagerness": "moderate"
}
]
}
</script>
href_matches のパターンは * がパスセグメントにマッチする。同一オリジン限定 が原則で、クロスオリジンURLはSpeculation Rules APIの対象外だ(別途 <link rel=prefetch> や103 Early Hintsを検討)。
list rules との使い分け
| ソース | 向いているケース | 注意 |
|---|---|---|
| list | ランディング→固定3ページ、ECのカテゴリTOP | URL変更時にJSON更新が必要 |
| document | ブログ一覧、ドキュメントTOC、パンくず | 除外条件(logout/cart)を必ず設計 |
特定リンクだけ除外するHTMLパターン
<!-- 投機対象外:外部リンク・ダウンロード・ログアウト -->
<a href="/blog/critical-rendering-path-最適化/">通常記事(投機対象)</a>
<a href="/logout" class="no-prerender">ログアウト</a>
<a href="/files/report.pdf" download>PDF</a>
<a href="https://example.com" rel="noopener" class="external-link">外部</a>
selector_matches: ".no-prerender" をwhere条件の not に入れておけば、クラス1つで制御できる。
Speculation-Rules HTTPヘッダー
HTMLへの埋め込みに加え、Speculation-Rules HTTPレスポンスヘッダー(Chrome 121+)で外部JSONファイルを参照できる。CDNやエッジで一括配信する場合、全ページのHTMLを改修せずにルールを適用できる。
基本構文
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Speculation-Rules: "/speculationrules.json"
構造化ヘッダーのため、値はダブルクォートで囲む必要がある。複数ファイルを指定する場合:
Speculation-Rules: "/rules/prerender.json", "/rules/prefetch.json"
JSONファイルの配信要件
public/speculationrules.json として配置する例:
{
"relative_to": "document",
"tag": "site-wide",
"prerender_until_script": [{
"where": {
"and": [
{ "href_matches": "/blog/*" },
{ "not": { "href_matches": "/admin/*" } }
]
},
"eagerness": "moderate"
}],
"prefetch": [{
"where": { "href_matches": "/blog/*" },
"eagerness": "moderate"
}]
}
参照先のレスポンスヘッダー:
HTTP/1.1 200 OK
Content-Type: application/speculationrules+json
Access-Control-Allow-Origin: *
Cache-Control: public, max-age=3600
"relative_to": "document" を指定すると、JSON内の相対URLがHTML文書のURL基準で解決される。省略時はJSONファイル自身のURLが基準になる。
Cloudflare Pages _headers の例
/*
Speculation-Rules: "/speculationrules.json"
/speculationrules.json
Content-Type: application/speculationrules+json
Cache-Control: public, max-age=3600
nginx の例
location / {
add_header Speculation-Rules '"/speculationrules.json"' always;
}
location = /speculationrules.json {
default_type application/speculationrules+json;
add_header Cache-Control "public, max-age=3600";
}
HTTPヘッダー方式は CSPでインラインスクリプトが禁止されているサイト でも、外部JSONだけを許可すればSpeculation Rulesを導入できる利点がある。
Safari・Firefoxへのフォールバック
2026年6月時点のブラウザ対応:
| ブラウザ | Speculation Rules | prerender_until_script |
|---|---|---|
| Chrome 109+ / Edge 109+ | ◎ | Origin Trial(144〜150) |
| Safari | フラグ付き(開発中) | 未対応 |
| Firefox | 未実装 | 未対応 |
Chromium以外ではJSONキーが無視されるだけで害はないが、先読みの恩恵も受けられない。段階的フォールバックを設計する。
機能検出
const supportsSpeculationRules =
HTMLScriptElement.supports?.('speculationrules') ?? false;
フォールバック階層
1. Speculation Rules(prerender / prerender_until_script + prefetch併記)
↓ 非対応
2. <link rel="preconnect"> でオリジン接続を事前確立
↓
3. ホバー時の <link rel="prefetch"> 注入(自前実装)
↓
4. [CRP最適化](/blog/critical-rendering-path-最適化/) + [HTTP/3](/blog/http2-http3-違い-パフォーマンス比較/)
非Chromium向けの最小prefetch実装
if (!HTMLScriptElement.supports?.('speculationrules')) {
const prefetched = new Set();
document.addEventListener('mouseover', (e) => {
const link = e.target.closest('a[href]');
if (!link || link.origin !== location.origin) return;
const href = link.href;
if (prefetched.has(href)) return;
prefetched.add(href);
const hint = document.createElement('link');
hint.rel = 'prefetch';
hint.href = href;
document.head.appendChild(hint);
}, { passive: true });
}
<link rel=prefetch>はHTTPキャッシュへの格納のみで、Speculation Rulesのprefetchほど強力ではない。Safariでは文書prefetchが帯域に余裕がある場合に限り有効だ。Firefoxは2026年時点でナビゲーションprefetchの標準実装がなく、この自前実装も効果は限定的——ベースラインのCRP・HTTP/3最適化がより重要になる。
prerender_until_scriptには必ず同一条件のprefetchルールを併記し、Chromeが利用可能な最強アクションを自動選択させる。User-Agentスニッフィングは不要だ。
パフォーマンスへの影響と計測
Speculation Rules APIの効果は Field Data(実ユーザー) で測るべきだ。Lab環境のLighthouse単体では「次ページへの遷移速度」は計測されない。
計測すべき指標
- click-to-LCP — リンククリックからLCPまで(WebPageTestの「Click to LCP」、または自前RUM)
- Navigation Timing API —
performance.getEntriesByType('navigation')のactivationStart(prerenderヒット時 > 0) - Prerender hit rate — 投機開始数に対する実ナビゲーション数の比率
- 帯域増加量 — CDNログまたはNetwork Information APIでの推定
- Core Web Vitals — 遷移先ページのLCP・INP(prerender過多でメインスレッド競合が起きないか)
activationStart で prerender ヒットを検出
function reportNavigationType() {
const [nav] = performance.getEntriesByType('navigation');
if (!nav) return;
const wasPrerendered = nav.activationStart > 0;
const clickToLCP = performance.getEntriesByType('largest-contentful-paint')
.filter((e) => e.startTime >= nav.startTime)
.sort((a, b) => b.startTime - a.startTime)[0];
const payload = {
wasPrerendered,
activationStart: nav.activationStart,
domContentLoaded: nav.domContentLoadedEventEnd - nav.startTime,
loadEvent: nav.loadEventEnd - nav.startTime,
lcp: clickToLCP ? clickToLCP.startTime - nav.startTime : null,
};
if (navigator.sendBeacon) {
navigator.sendBeacon('/api/rum/navigation', JSON.stringify(payload));
}
}
if (document.readyState === 'complete') {
reportNavigationType();
} else {
window.addEventListener('load', reportNavigationType);
}
activationStart > 0 は prerenderがアクティベーションされた 証拠だ。Analyticsに navigation_type: prerender として送り、Conversionファネルでprerenderユーザーと通常ユーザーを比較する。
帯域とメモリのトレードオフ
| シナリオ | 追加帯域(目安/ユーザー/セッション) | 主なリスク |
|---|---|---|
| conservative prefetch | 50〜200KB | 低。未訪問ページの無駄fetch |
| moderate prefetch | 200KB〜1MB | 中。ホバーしたが遷移しなかった分 |
| moderate prerender | 1〜5MB | 高。JS実行・DOMメモリ |
| immediate prerender × 10 | 10〜50MB | 非常に高。モバイル回線で顕著 |
HTTP/2のマルチプレクシング により先読みリクエストは既存接続上で並列化されるが、サーバー・CDNの転送量課金 は増える。Cloudflare等では投機トラフィックも通常転送にカウントされるため、導入前にCDNダッシュボードのベースラインを記録しておく。
- 効きやすい — 記事・ドキュメントサイト(テキストLCP、JS比較的軽量)、同一セッション内の回遊率が高いECカテゴリ
- 効きにくい — 1ページ完結LP、ログイン必須のSPA(認証状態が複雑)、ページ重量10MB超(動画・WebGL多数)
プライバシーとセキュリティの考慮事項
投機ルールは ユーザーがまだ明示的にナビゲーションしていないURL へリクエストを送る。プライバシー・セキュリティ・計測の観点で、本番導入前に必ず設計すべき項目がある。
1. 同一オリジン原則
Speculation Rules APIのprefetch/prerenderは 同一オリジン に限定される。クロスオリジン先読みは <link rel=prefetch> でも制限があり、RefererポリシーとCORSの理解が必要だ。referrer_policy キーで投機リクエストのRefererを制御できる。
<script type="speculationrules">
{
"prefetch": [
{
"source": "document",
"where": { "href_matches": "/docs/*" },
"eagerness": "moderate",
"referrer_policy": "strict-origin-when-cross-origin"
}
]
}
</script>
2. prerender における JavaScript 副作用
prerender中は 非表示だが完全なBrowsing Context としてJSが実行される。典型的な副作用は次のとおり。
- Analytics — GA4 / gtag / Meta Pixelがpageviewを送信(未訪問ユーザーとしてカウント)
- 認証 — トークンリフレッシュAPIが走り、セッション状態が変わる
- A/Bテスト — バリアント割り当てが先に確定し、表示前に実験グループが固定
- 広告 — インプレッション計測が発火
- Service Worker — fetchイベントがprerenderリクエストを処理
対策として Supports-Loading-Mode レスポンスヘッダーを返し、サーバー側でprerender/prefetchを識別する。
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Supports-Loading-Mode: credentialed-prerender, credentialed-prerender-until-script
Cache-Control: private, max-age=0
Vary: Sec-Fetch-Dest, Sec-Fetch-Mode
クライアント側では document.prerendering(Prerendering API)で分岐する。
if (document.prerendering) {
// prerender中はAnalytics送信をスキップ
window.__DEFER_ANALYTICS__ = true;
} else {
initAnalytics();
}
document.addEventListener('prerenderingchange', () => {
if (!document.prerendering && window.__DEFER_ANALYTICS__) {
initAnalytics();
delete window.__DEFER_ANALYTICS__;
}
});
3. No-Vary-Search と URL バリアント
クエリパラメータでコンテンツが変わるページ(?utm_*、?variant=b)では、投機キャッシュと実ナビゲーションの不一致(cache poisoning的な表示ズレ)が起きうる。No-Vary-Search レスポンスヘッダーで、投機時に無視するクエリキーを宣言する。
No-Vary-Search: key-order, params=("utm_source" "utm_medium" "utm_campaign")
4. 除外すべきURLパターン
投機ルールから 必ず除外 すべき典型的なパス。
| パス | 理由 |
|---|---|
/logout | 意図しないログアウト |
/cart / /checkout/* | 在庫・決済状態の不整合 |
/account/* | 個人情報の先読み |
/api/* | RESTエンドポイントへのGET副作用 |
target=_blank 外部リンク | クロスオリジン・新規タブ |
5. CSP との関係
Content-Security-Policyの script-src は投機中も適用される。prerender_until_scriptは 最初のscriptで停止 するため、CSP nonce/hashの不一致で想定外に早期停止するケースは少ないが、inline scriptが先頭にある ページでは prerender_until_script の恩恵が薄れる。CSP設計は CSP段階導入ガイド と合わせて確認する。
サーバー側の設定
投機ルールはクライアント側の宣言だが、サーバーがprerender/prefetchを正しく処理 しないと効果半減・副作用増大の両方が起きる。
Supports-Loading-Mode ヘッダー
HTMLレスポンスに次のヘッダーを付与する。
Supports-Loading-Mode: credentialed-prerender, credentialed-prerender-until-script
Cookie付き(credentialed)ナビゲーションのprerenderを許可する宣言だ。未設定の場合、Chromeはno-corsモードで投機し、パーソナライズされたHTMLが取得できず キャッシュミス になる。
Middleware での分岐(Next.js / Express)
// Express 例: Sec-Fetch-Dest で投機リクエストを識別
function speculationAwareMiddleware(req, res, next) {
const secFetchDest = req.headers['sec-fetch-dest'];
const secFetchMode = req.headers['sec-fetch-mode'];
const isPrefetch = secFetchDest === 'empty' && secFetchMode === 'cors';
const isPrerender = secFetchDest === 'iframe' || req.headers['sec-purpose'] === 'prefetch';
res.setHeader(
'Supports-Loading-Mode',
'credentialed-prerender, credentialed-prerender-until-script'
);
res.setHeader(
'No-Vary-Search',
'key-order, params=("utm_source" "utm_medium" "utm_campaign")'
);
if (isPrerender) {
req.isPrerenderRequest = true;
} else if (isPrefetch) {
req.isPrefetchRequest = true;
}
next();
}
Next.js App Routerでは middleware.ts で Sec-Fetch-Dest を参照し、prerender時にPersonalizationをスキップするパターンが一般的だ。
103 Early Hints との併用
103 Early Hintsは 現在のページレスポンス中 に次リクエストのLinkヘッダーを先行送信する。Speculation Rules APIと競合するわけではなく、HTML到着前のサブリソース先読み として相補的に使える。TTFBが長いオリジンでは Early Hints + moderate prerender の組み合わせが有効だ。
DevTools でのデバッグ手順
Chrome DevTools → Application → Speculative loads パネルを開く
ページ上でリンクにホバーし、prefetch/prerenderエントリが追加されるか確認
Status列で Success / Failed / Not triggered の理由を読む
Networkパネルで Initiator が speculation rules であるリクエストをフィルタ
Performance Insights → Navigate シナリオで activationStart を記録
chrome://predictors または chrome://net-internals/#prerender で内部状態を確認(上級者向け)
chrome://flags/#speculation-rules-immediate を有効にすると、eagerness: immediate の挙動をローカルで強制テストできる。本番相当の検証は moderate/conservative で行うこと。
よくある DevTools 表示と対処
| Status | 意味 | 対処 |
|---|---|---|
Eligible | ルールに合致、発火待ち | eagerness条件(ホバー200ms等)を満たす |
Success | 投機完了 | — |
Failed: limits exceeded | 同時上限超過 | eagernessを下げる、list rulesのURL数を減らす |
Failed: unsupported | サーバーがcredentialed prerender非対応 | Supports-Loading-Modeヘッダーを追加 |
Not triggered: cross-origin | クロスオリジン | 同一オリジンリンクのみ対象に |
フレームワーク別実装パターン
Astro / 静的サイト
レイアウトコンポーネントの <head> に speculation rules を1箇所で注入する。
---
// BaseLayout.astro の head 内
---
<script type="speculationrules" set:html={JSON.stringify({
prefetch: [{
source: 'document',
where: {
and: [
{ href_matches: '/blog/*' },
{ not: { href_matches: '/blog/*/draft' } },
],
},
eagerness: 'moderate',
}],
})} />
React SPA(クライアントルーティング併用)
Speculation Rules APIは フルページナビゲーション が前提だ。React Routerの <Link> でpreventDefaultしている場合、投機は <a href> の通常クリックにのみ有効。SPA化したルートでは View Transitions API やルーターレベルの prefetch(React Router v6.4+ lazy + prefetch)と役割分担を明確にする。
// 通常の <a href> を維持し、Reactがハイドレーション後にルーティングを引き継ぐ構成
export function ArticleLink({ slug, title }) {
return (
<a href={`/blog/${slug}/`} className="article-link">
{title}
</a>
);
}
WordPress / CMS
functions.php またはプラグインで wp_head に出力する。キャッシュプラグイン(WP Rocket等)は Supports-Loading-Mode ヘッダーを落とさないよう設定確認が必要。
<?php
function output_speculation_rules() {
if (is_admin()) return;
$rules = [
'prefetch' => [[
'source' => 'document',
'where' => [
'and' => [
['href_matches' => '/blog/*'],
['not' => ['href_matches' => '/wp-admin/*']],
],
],
'eagerness' => 'moderate',
]],
];
echo '<script type="speculationrules">' . wp_json_encode($rules) . '</script>';
}
add_action('wp_head', 'output_speculation_rules', 1);
実践チェックリスト:本番導入前
現状のサイト内回遊率(記事→記事遷移率)とclick-to-LCPを計測し、ROI見込みを判断
除外URL(logout/cart/checkout/admin/api)をwhere条件に列挙
Supports-Loading-Mode と No-Vary-Search ヘッダーをHTMLレスポンスに追加
Analytics / 広告 / A/Bテストに document.prerendering 分岐を実装
Phase 1: conservative + prefetch のみを1週間、CDN転送量を監視
Phase 2: moderate + prerender_until_script(Chrome 144+ Trial)または moderate prerender
DevTools Speculative loads と RUM activationStart でヒット率を週次レビュー
モバイル4G環境で帯域増とバッテリー影響をサンプリング計測
よくある落とし穴
- 全リンク immediate prerender — 上限10件でも帯域・CPU負荷が跳ね上がる。document rulesではimmediateを避ける
- Supports-Loading-Mode 未設定 — ログイン後のパーソナライズHTMLがprerenderキャッシュに載らず効果ゼロ
- Analytics二重計数 — prerender中のpageviewを除外せず、PVが水増しされる
- クエリパラメータ付きURL — No-Vary-Search未設定で、UTM付き実ナビゲーションがキャッシュミス
- 重いサードパーティJS — prerenderが広告・チャットWidgetまで実行し、メインスレッドを圧迫
prefetch / prerender / prerender_until_script 選択フロー
ユーザーが次ページへ行く確率は?
├─ 低い(LP・単一CTA)→ 投機なし。CRP最適化を優先
├─ 中(たまに回遊)→ conservative prefetch
├─ 高(ブログ・ドキュメント)→ moderate prefetch
│ └─ JS軽量 & 副作用対策済み → moderate prerender_until_script(Chrome 144+)
│ └─ 計測OK & Analytics分岐済み → moderate prerender
└─ 非常に高(固定導線3ページ)→ immediate prefetch + moderate prerender
関連記事
この記事は Webパフォーマンス テーマの一環です。あわせて読むと理解が深まる関連記事をまとめました。
| トピック | 記事 |
|---|---|
| fetchpriority属性でLCP画像を最適化する | fetchpriority属性でLCP画像を最適化する|2026年実践ガイド |
| Web Vitals INP改善ガイド | Web Vitals INP改善ガイド|scheduler.yield・Long Task・Input Delay対策(2026) |
| content-visibility: auto 完全ガイド | content-visibility: auto 完全ガイド|遅延レンダリングと長尺ページ最適化 2026 |
| Server-Timing API 完全ガイド | Server-Timing API 完全ガイド|Express ミドルウェアと Chrome DevTools 連携 |
| Brotli vs Gzip 圧縮比較 | Brotli vs Gzip 圧縮比較|nginx静的・動的設定とCDN実践ガイド |
| CSS/JSを圧縮(Minify)するメリット | CSS/JSを圧縮(Minify)するメリット|サイト高速化の基本 |
| Service Worker キャッシュ戦略ガイド | Service Worker キャッシュ戦略ガイド|PWA の cache-first・network-first・SWR・Workbox 設計 |
| View Transitions API 完全ガイド | View Transitions API 完全ガイド|SPA・MPA ページ遷移と Astro/React 統合 |
| WebP変換で画質が落ちる原因と最適な設定 | WebP変換で画質が落ちる原因と最適な設定 |
| 画像圧縮とWebP変換 | 画像圧縮とWebP変換|PageSpeed改善の基本 |
| Web APIのエラーハンドリング設計 | Web APIのエラーハンドリング設計|RFC 9457・error_code・400/422/409の使い分け |
| WebスクレイピングのAnti-Bot対策 | WebスクレイピングのAnti-Bot対策|WAF・Cloudflare・フィンガープリント・CAPTCHAの技術解説 |
まとめ
Speculation Rules APIは、次のナビゲーションを先読み・先描画 し、サイト内回遊の体感速度を改善する2020年代の標準手段だ。要点を整理する。
- prefetch — 低リスク。TTFB短縮。まず conservative document rules から
- prerender — 高効果・高コスト。Analytics分岐と Supports-Loading-Mode が必須
- eagerness — moderate(200msホバー)がバランス良。document rulesで immediate は危険
- document rules — CMS連動でメンテフリー。logout/cart等の除外を忘れない
- Chrome 144 prerender_until_script — Origin Trial中の中間層。prefetchフォールバック必須
現在ページの初回表示は クリティカルレンダリングパス最適化、ネットワーク層の効率は HTTP/2とHTTP/3の比較 と合わせて設計すると、初回訪問・回遊・プロトコル の3軸で包括的なWebパフォーマンス戦略が完成する。
まずDevToolsの Speculative loads パネルを開き、ブログ記事リンク1本に conservative prefetch を設定する——この1行から、計測可能な改善サイクルが始まる。