公開日: 2022 年 12 月 2 日、最終更新日: 2025 年 8 月 17 日
Chrome チームは、ユーザーが次に閲覧する可能性が高いページの完全なプリレンダリングを復活させました。
プリレンダリングの簡単な歴史
以前、Chrome は <link rel="prerender" href="/next-page">
リソース ヒントをサポートしていましたが、Chrome 以外では広くサポートされておらず、表現力に優れた API ではありませんでした。
リンク rel=prerender
ヒントを使用したこの従来の事前レンダリングは、NoState Prefetch に置き換えられました。これは、将来のページに必要なリソースをフェッチしますが、ページを完全に事前レンダリングしたり、JavaScript を実行したりしません。NoState Prefetch はリソースの読み込みを改善することでページのパフォーマンス向上に役立ちますが、完全な事前レンダリングのようにページを瞬時に読み込むことはできません。
Chrome チームは、Chrome にフル プリレンダリングを再び導入しました。既存の使用状況との複雑さを回避し、プリレンダリングの将来的な拡張を可能にするため、この新しいプリレンダリング メカニズムでは <link rel="prerender"...>
構文は使用されません。この構文は NoState Prefetch 用に残され、将来的に廃止される予定です。
ページの事前レンダリングはどのように行われますか?
ページは次の 4 つの方法のいずれかでプリレンダリングできます。いずれもナビゲーションの高速化を目的としています。
- Chrome のアドレスバー(「アドレスバー」とも呼ばれます)に URL を入力すると、過去の閲覧履歴に基づいて、そのページにアクセスする可能性が高いと Chrome が判断した場合、そのページが自動的にプリレンダリングされることがあります。
- ブックマーク バーを使用している場合、ブックマーク ボタンのいずれかにポインタを合わせると、Chrome がページを自動的に事前レンダリングすることがあります。
- Chrome のアドレスバーに検索キーワードを入力すると、検索エンジンから指示があった場合に、検索結果ページが自動的にプリレンダリングされることがあります。
- サイトは Speculation Rules API を使用して、どのページを事前レンダリングするかを Chrome にプログラムで伝えることができます。これは
<link rel="prerender"...>
の機能を置き換えるもので、サイトはページ上の投機ルールに基づいてページを事前にレンダリングできます。これらはページに静的に存在することも、ページ所有者の判断で JavaScript によって動的に挿入することもできます。
いずれの場合も、プリレンダリングは、ページが非表示のバックグラウンド タブで開かれ、そのプリレンダリングされたページでフォアグラウンド タブを置き換えることで「アクティブ化」されたかのように動作します。ページが完全にプリレンダリングされる前にアクティブ化された場合、その現在の状態は「フォアグラウンド」になり、読み込みが続行されます。つまり、引き続き良いスタートを切ることができます。
事前レンダリングされたページは非表示の状態で開かれるため、侵入的な動作を引き起こす API の多く(プロンプトなど)はこの状態では有効にならず、ページが有効になるまで遅延されます。ごくまれに、この処理がまだ完了していない場合は、プリレンダリングがキャンセルされます。Chrome チームは、プリレンダリングのキャンセル理由を API として公開し、このようなエッジケースを特定しやすくするために DevTools の機能を強化する作業に取り組んでいます。
プリレンダリングの影響
プリレンダリングにより、次の動画に示すように、ほぼ瞬時にページを読み込むことができます。
このサイトはすでに高速ですが、プリレンダリングによってユーザー エクスペリエンスが向上する様子を確認できます。そのため、サイトの Core Web Vitals にも直接的な影響を与える可能性があります。LCP はほぼゼロになり、CLS は減少(読み込み時の CLS は初期ビューの前に発生するため)、INP は改善されます(読み込みはユーザーが操作する前に完了するため)。
ページが完全に読み込まれる前にアクティブ化された場合でも、ページの読み込みを先に開始することで、読み込みエクスペリエンスが向上します。事前レンダリング中にリンクが有効になると、事前レンダリング ページがメインフレームに移動して読み込みが続行されます。
ただし、プリレンダリングでは追加のメモリとネットワーク帯域幅が使用されます。ユーザーのリソースを消費して過剰にプリレンダリングしないように注意してください。ページに移動する可能性が高い場合にのみプリレンダリングします。
アナリティクスで実際のパフォーマンスの影響を測定する方法について詳しくは、パフォーマンスの測定のセクションをご覧ください。
Chrome のアドレスバーの予測候補を表示する
最初のユースケースでは、chrome://predictors
ページで Chrome の URL 予測を確認できます。

緑色の線は、プリレンダリングをトリガーするのに十分な信頼性があることを示します。この例では、「s」と入力すると妥当な信頼度(オレンジ)が得られますが、「sh」と入力すると、Chrome はほぼ常に https://sheets.google.com
に移動すると判断します。
このスクリーンショットは、比較的新しい Chrome のインストールで、信頼度 0 の予測を除外した状態で撮影されたものです。ただし、独自の予測を表示すると、エントリが大幅に増え、十分な信頼度レベルに達するために必要な文字数が増える可能性があります。
これらの予測子は、アドレスバーに表示される候補オプションの基盤にもなっています。

Chrome は、入力内容や選択内容に基づいて予測ツールを継続的に更新します。
- 信頼度が 50% を超える場合(琥珀色で表示)、Chrome はドメインに事前に接続しますが、ページをプリレンダリングしません。
- 信頼度が 80% を超える場合(緑色で表示)、Chrome は URL をプリレンダリングします。
Speculation Rules API
Speculation Rules API のプリレンダリング オプションでは、ウェブ デベロッパーは JSON の指示をページに挿入して、プリレンダリングする URL をブラウザに通知できます。
<script type="speculationrules"> { "prerender": [ { "urls": ["next.html", "next2.html"] } ] } </script>
または、ドキュメント ルール(Chrome 121 以降で利用可能)を使用します。このルールでは、href
セレクタ(URL パターン API に基づく)または CSS セレクタに基づいて、ドキュメント内のリンクをプリレンダリングします。
<script type="speculationrules"> { "prerender": [{ "where": { "and": [ { "href_matches": "/*" }, { "not": {"href_matches": "/wp-admin"}}, { "not": {"href_matches": "/*\\?*(^|&)add-to-cart=*"}}, { "not": {"selector_matches": ".do-not-prerender"}}, { "not": {"selector_matches": "[rel~=nofollow]"}} ] } }] } </script>
Chrome チームは、サイトに投機ルールを追加する手順を説明する Speculation Rules Codelab を用意しています。
Eagerness
eagerness
設定は、投機をいつ開始するかを示すために使用されます。これは、ドキュメント ルールで特に役立ちます。
immediate
: できるだけ早く、つまり、投機ルールが検出されたらすぐに投機を行う場合に使用します。eager
: 元々はimmediate
と同じ動作でしたが、Chrome 141 以降は 5 ミリ秒のマウスオーバーに変更され、モバイルでは シンプルなビューポート ヒューリスティックにさらに変更される予定です。moderate
: パソコンでは、ユーザーがリンクにカーソルを 200 ミリ秒合わせた場合(またはpointerdown
イベントがそれより早く発生した場合やhover
イベントのないモバイルで発生した場合)に投機を行います。モバイルでは、複雑なビューポート ヒューリスティックに基づいてこの処理を行うように変更を導入しています。conservative
: ユーザーがポインタダウンまたはタッチダウンしたときに投機を行います。
list
ルールのデフォルトの eagerness
は immediate
です。moderate
オプションと conservative
オプションを使用すると、ユーザーが操作する URL を特定のリストに限定する list
ルールを作成できます。ただし、多くの場合、適切な where
条件を含む document
ルールの方が適切です。
document
ルールのデフォルトの eagerness
は conservative
です。ドキュメントは多くの URL で構成される可能性があるため、document
ルールに immediate
または eager
を使用する場合は注意が必要です(次の Chrome の上限セクションも参照してください)。
使用する eagerness
設定は、サイトによって異なります。軽量な静的サイトの場合、投機的実行を積極的に行ってもコストはほとんどかからず、ユーザーにとって有益な可能性があります。アーキテクチャが複雑で、ページ ペイロードが大きいサイトでは、ユーザーの意図を示すポジティブなシグナルがより多く得られるまで推測の頻度を減らし、無駄を減らすことを優先する場合があります。
moderate
オプションは中間的な選択肢です。多くのサイトでは、ポインタをリンクの上に 200 ミリ秒間置いたとき、または pointerdown イベントでリンクをプリレンダリングする次の推測ルールを基本として使用することで、推測ルールの強力な実装のメリットを得られます。
<script type="speculationrules"> { "prerender": [{ "where": { "href_matches": "/*" }, "eagerness": "moderate" }] } </script>
Prefetch
推測ルールは、完全なプリレンダリングを行わずに、ページのプリフェッチのみを行う場合にも使用できます。これは、プリレンダリングへの道のりの最初のステップとして有効なことがよくあります。
<script type="speculationrules"> { "prefetch": [ { "urls": ["next.html", "next2.html"] } ] } </script>
Chrome の上限
Chrome には、Speculation Rules API の過剰な使用を防ぐための制限が設けられています。
熱意 | Prefetch | Prerender |
---|---|---|
immediate / eager | 50 | 10 |
moderate / conservative | 2(FIFO) | 2(FIFO) |
moderate
と conservative
の設定はユーザーの操作に依存し、先入れ先出し(FIFO)方式で動作します。上限に達すると、新しい投機によって最も古い投機がキャンセルされ、新しい投機に置き換えられてメモリが節約されます。キャンセルされた投機は、たとえばそのリンクに再度カーソルを合わせることで、再度トリガーできます。これにより、その URL が再度投機され、最も古い投機がプッシュアウトされます。この場合、以前の投機では、その URL のキャッシュ可能なリソースが HTTP キャッシュにキャッシュ保存されているため、それ以降の投機ではコストが削減されます。そのため、上限は 2 という控えめな値に設定されています。静的リストルールはユーザー アクションによってトリガーされないため、上限が高くなっています。ブラウザは、どのルールがいつ必要になるかを把握できないためです。
immediate
と eager
の上限も動的であるため、list
URL スクリプト要素を削除すると、削除された投機をキャンセルすることで容量が作成されます。
また、Chrome では、次のような特定の条件下で投機的実行が使用されないようにします。
- Save-Data。
- 省エネモードが有効で、バッテリー残量が少ない場合。
- メモリの制約。
- 「ページをプリロードする」の設定がオフになっている場合(uBlock Origin などの Chrome 拡張機能によって明示的にオフにされている場合も含む)。
- バックグラウンド タブで開かれたページ。
また、Chrome では、事前レンダリングされたページでクロスオリジン iframe が有効化されるまでレンダリングされません。
これらの条件はすべて、過剰な投機がユーザーに悪影響を及ぼす場合に、その影響を軽減することを目的としています。
ページに推測ルールを含める方法
投機ルールは、ページの HTML に静的に含めることも、JavaScript によってページに動的に挿入することもできます。
- 静的に含まれる投機ルール: たとえば、ニュース メディア サイトやブログでは、ユーザーの大部分が次に移動する可能性が高い最新の記事をプリレンダリングできます。また、
moderate
またはconservative
を含むドキュメント ルールを使用して、ユーザーがリンクを操作する際に投機を行うこともできます。 - 動的に挿入される投機ルール: アプリケーション ロジックに基づく場合、ユーザーに合わせてパーソナライズされる場合、他のヒューリスティックに基づく場合があります。
リンクにカーソルを合わせたり、リンクをクリックしたりするなどのアクションに基づいて動的挿入を優先する場合は(多くのライブラリが過去に <link rel=prefetch>
で行ってきたように)、ドキュメント ルールを確認することをおすすめします。ドキュメント ルールを使用すると、ブラウザで多くのユースケースを処理できます。
投機的実行ルールは、メインフレームの <head>
または <body>
のいずれかに追加できます。サブフレームの投機ルールは実行されません。プリレンダリングされたページの投機ルールは、そのページがアクティブになったときにのみ実行されます。
Speculation-Rules
HTTP ヘッダー
推測ルールは、ドキュメントの HTML に直接含めるのではなく、Speculation-Rules
HTTP ヘッダーを使用して配信することもできます。これにより、ドキュメントの内容自体を変更することなく、CDN によるデプロイを容易に行うことができます。
Speculation-Rules
HTTP ヘッダーがドキュメントとともに返され、投機ルールを含む JSON ファイルの場所を指します。
Speculation-Rules: "/speculationrules.json"
このリソースは正しい MIME タイプを使用し、クロスオリジン リソースの場合は CORS チェックに合格する必要があります。
Content-Type: application/speculationrules+json Access-Control-Allow-Origin: *
相対 URL を使用する場合は、投機ルールの "relative_to": "document"
キーを含めることをおすすめします。それ以外の場合、相対 URL は投機ルール JSON ファイルの URL を基準とします。これは、同じオリジンのリンクの一部またはすべてを選択する必要がある場合に特に便利です。
推測ルールのタグフィールド
投機ルールの JSON 構文で、個々のルールレベルで「タグ」を追加することもできます。
{ "prefetch": [ "urls": ["next.html"], "tag": "my-prefetch-rules" ], "prerender": [ "urls": ["next2.html"], "tag": "my-prerender-rules" ], }
または、ルールセット内のすべての投機ルールに対して全体レベルで指定します。
{ "tag": "my-rules", "prefetch": [ "urls": ["next.html"] ], "prerender": [ "urls": ["next2.html"] ], }
このタグは Sec-Speculation-Tags
HTTP ヘッダーに反映され、サーバーで投機的実行ルールをフィルタリングするために使用できます。次の例に示すように、投機が複数のルールでカバーされている場合、Sec-Speculation-Tags
HTTP ヘッダーに複数のタグを含めることができます。
Sec-Speculation-Tags: null Sec-Speculation-Tags: null, "cdn-prefetch" Sec-Speculation-Tags: "my-prefetch-rules" Sec-Speculation-Tags: "my-prefetch-rules", "my-rules", "cdn-prefetch"
一部の CDN は推測ルールを自動的に挿入しますが、この機能によってオリジン サーバーの使用量が増加しないように、エッジ キャッシュに保存されていないページに対する推測をブロックします。タグを使用すると、デフォルトのルールセットによって開始された投機を特定できますが、サイトによって追加されたルールは引き続きオリジンに渡されます。
タグはツールでも役立ちます。たとえば、DevTools にタグを追加することを検討しています。
推測ルール target_hint
フィールド
推測ルールには target_hint
フィールドを含めることもできます。このフィールドには、ページがプリレンダリングされたコンテンツをアクティブ化することを想定している場所を示す有効なブラウジング コンテキスト名またはキーワードが含まれます。
<script type=speculationrules> { "prerender": [{ "target_hint": "_blank", "urls": ["next.html"] }] } </script>
このヒントにより、target="_blank"
リンクのプリレンダリング推測を処理できます。
<a target="_blank" href="next.html">Open this link in a new tab</a>
現在のところ、Chrome では "target_hint": "_blank"
と "target_hint": "_self"
(指定しない場合のデフォルト)のみがサポートされており、プリレンダリングでのみサポートされています。プリフェッチはサポートされていません。
target_hint
は urls
投機ルールでのみ必要です。ドキュメント ルールの場合、target
はリンク自体からわかります。
投機ルールと SPA
投機的ルールのサポート対象は、ブラウザで管理されるフルページ ナビゲーションのみです。シングルページ アプリ(SPA)やアプリシェルページは対象外です。これらのアーキテクチャでは、ドキュメントの取得は使用されず、データやページの API 取得または部分取得が行われ、取得されたデータやページが処理されて現在のページに表示されます。いわゆる「ソフト ナビゲーション」に必要なデータは、推測ルールの外でアプリによってプリフェッチできますが、プリレンダリングはできません。
投機ルールを使用すると、前のページからアプリケーション自体をプリレンダリングできます。これにより、一部の SPA で発生する初期読み込みの追加費用を相殺できます。ただし、アプリ内のルート変更はプリレンダリングできません。
投機ルールをデバッグする
この新しい API の表示とデバッグに役立つ Chrome DevTools の新機能については、投機ルールのデバッグに関する専用の記事をご覧ください。
複数の推測ルール
同じページに複数の投機的ルールを追加することもできます。その場合、既存のルールに追加されます。したがって、次のさまざまな方法では、one.html
と two.html
の両方がプリレンダリングされます。
URL のリスト:
<script type="speculationrules"> { "prerender": [ { "urls": ["one.html", "two.html"] } ] } </script>
複数の speculationrules
スクリプト:
<script type="speculationrules"> { "prerender": [ { "urls": ["one.html"] } ] } </script> <script type="speculationrules"> { "prerender": [ { "urls": ["two.html"] } ] } </script>
1 つの speculationrules
のセット内に複数のリストがある
<script type="speculationrules"> { "prerender": [ { "urls": ["one.html"] }, { "urls": ["two.html"] } ] } </script>
No-Vary-Search
のサポート
ページをプリフェッチまたはプリレンダリングする際、特定の URL パラメータ(技術的には検索パラメータと呼ばれます)は、サーバーから実際に配信されるページには重要ではなく、クライアントサイドの JavaScript でのみ使用される場合があります。
たとえば、Google アナリティクスではキャンペーンの測定に UTM パラメータが使用されますが、通常はサーバーから異なるページが配信されることはありません。つまり、page1.html?utm_content=123
と page1.html?utm_content=456
はサーバーから同じページを配信するため、同じページをキャッシュから再利用できます。
同様に、アプリケーションではクライアントサイドでのみ処理される他の URL パラメータが使用されることがあります。
No-Vary-Search 提案では、サーバーが配信されるリソースに違いをもたらさないパラメータを指定できます。これにより、ブラウザはこれらのパラメータのみが異なるドキュメントの以前にキャッシュに保存されたバージョンを再利用できます。これは、プリフェッチとプリレンダリングの両方のナビゲーション投機について、Chrome(および Chromium ベースのブラウザ)でサポートされています。
投機ルールでは、expects_no_vary_search
を使用して No-Vary-Search
HTTP ヘッダーが返されることが想定される場所を指定できます。これにより、回答が表示される前に不要なダウンロードを回避できます。
<script type="speculationrules"> { "prefetch": [{ "urls": ["/products"], "expects_no_vary_search": "params=(\"id\")" }] } </script> <a href="/products?id=123">Product 123</a> <a href="/products?id=124">Product 124</a>
この例では、/products
の初期ページ HTML は商品 ID 123
と 124
の両方で同じです。ただし、最終的には、JavaScript を使用して id
検索パラメータで商品データを取得するクライアントサイド レンダリングに基づいてページの内容が異なります。そのため、その URL を積極的にプリフェッチし、id
検索パラメータにページを使用できることを示す No-Vary-Search
HTTP ヘッダーを返す必要があります。
ただし、プリフェッチが完了する前にユーザーがリンクをクリックすると、ブラウザが /products
ページを受信していない可能性があります。この場合、ブラウザは No-Vary-Search
HTTP ヘッダーが含まれるかどうかを認識しません。ブラウザは、リンクを再度取得するか、プリフェッチが完了するまで待って No-Vary-Search
HTTP ヘッダーが含まれているかどうかを確認するかを選択します。expects_no_vary_search
設定により、ブラウザはページ レスポンスに No-Vary-Search
HTTP ヘッダーが含まれることが想定されることを認識し、そのプリフェッチが完了するまで待機します。
No-Vary-Search
は HTTP 構造化ヘッダーであるため、スペースで区切って expects_no_vary_search
に複数のパラメータを追加することもできます。
"expects_no_vary_search": "params=(\"param1\" \"param2\" \"param3\")"
推測ルールの制限と今後の機能強化
推測ルールは同じタブ内で開かれたページに限定されますが、この制限を緩和する取り組みを進めています。
デフォルトでは、投機は同一オリジン ページに制限されています。投機的同一サイト クロスオリジン ページ(例: https://a.example.com
が https://b.example.com
のページをプリレンダリングする)。これを使用するには、投機的ページ(この例では https://b.example.com
)が Supports-Loading-Mode: credentialed-prerender
HTTP ヘッダーを含めることでオプトインする必要があります。そうしないと、Chrome は投機をキャンセルします。
将来のバージョンでは、事前レンダリングされたページに Cookie が存在せず、事前レンダリングされたページが同様の Supports-Loading-Mode: uncredentialed-prerender
HTTP ヘッダーでオプトインしている限り、同一サイト以外のクロスオリジン ページの事前レンダリングも許可される可能性があります。
投機的ルールはすでにクロスオリジン プリフェッチをサポートしていますが、クロスオリジン ドメインの Cookie が存在しない場合に限られます。ユーザーが以前にそのサイトにアクセスしたときに Cookie が存在する場合、投機は使用されず、デベロッパー ツールに失敗が表示されます。
現在の制限を踏まえると、可能な限り内部リンクと外部リンクの両方でユーザー エクスペリエンスを改善できるパターンは、同一オリジン URL を事前レンダリングし、クロスオリジン URL をプリフェッチすることです。
<script type="speculationrules"> { "prerender": [ { "where": { "href_matches": "/*" }, "eagerness": "moderate" } ], "prefetch": [ { "where": { "not": { "href_matches": "/*" } }, "eagerness": "moderate" } ] } </script>
デフォルトでクロスオリジン リンクのクロスオリジン推測を防ぐ制限は、セキュリティ上必要です。これは、クロスオリジン宛先に対する <link rel="prefetch">
の改善です。クロスオリジン宛先では、Cookie は送信されませんが、プリフェッチは試行されます。その結果、再送信が必要な無駄なプリフェッチが発生するか、最悪の場合、誤ったページが読み込まれます。
Speculation Rules API のサポートを検出する
標準の HTML チェックで Speculation Rules API のサポートを検出できます。
if (HTMLScriptElement.supports && HTMLScriptElement.supports('speculationrules')) { console.log('Your browser supports the Speculation Rules API.'); }
JavaScript を使用して投機ルールを動的に追加する
JavaScript を使用して prerender
推測ルールを追加する例を次に示します。
if (HTMLScriptElement.supports && HTMLScriptElement.supports('speculationrules')) { const specScript = document.createElement('script'); specScript.type = 'speculationrules'; specRules = { prerender: [ { urls: ['/next.html'], }, ], }; specScript.textContent = JSON.stringify(specRules); console.log('added speculation rules to: next.html'); document.body.append(specScript); }
JavaScript の挿入を使用した Speculation Rules API のプリレンダリングのデモは、プリレンダリングのデモページでご覧いただけます。
innerHTML
を使用して <script type = "speculationrules">
要素を DOM に直接挿入しても、セキュリティ上の理由から投機ルールは登録されません。そのため、前述のように追加する必要があります。ただし、新しいリンクを含む innerHTML
を使用して動的に挿入されたコンテンツは、ページの既存のルールによって検出されます。
同様に、Chrome デベロッパー ツールの [要素] パネルを直接編集して <script type = "speculationrules">
要素を追加しても、投機ルールの登録は行われません。代わりに、この要素を DOM に動的に追加するスクリプトをコンソールから実行して、ルールを挿入する必要があります。
タグ マネージャーを使用して投機ルールを追加する
Google タグ マネージャー(GTM)などのタグ マネージャーを使用して投機ルールを追加するには、前述の理由から、GTM を介して <script type = "speculationrules">
要素を直接追加するのではなく、JavaScript を介して挿入する必要があります。

この例では、GTM が const
をサポートしていないため、var
を使用しています。
推測ルールをキャンセルする
投機的ルールを削除すると、事前レンダリングがキャンセルされます。ただし、この時点でリソースはすでにプリレンダリングの開始に使用されている可能性が高いため、プリレンダリングをキャンセルする必要がある可能性がある場合は、プリレンダリングしないことをおすすめします。一方、キャッシュに保存されたリソースは再利用できるため、キャンセルが無駄になることはなく、今後の投機やナビゲーションに役立つ可能性があります。
prefetchCache
ディレクティブと prerenderCache
ディレクティブを含む Clear-Site-Data
HTTP ヘッダーを使用して、投機的処理をキャンセルすることもできます。
これは、サーバーで状態が変更された場合に役立ちます。たとえば、「カートに追加」API やログイン API、ログアウト API を呼び出す場合などです。
理想的には、これらの状態の更新は Broadcast Channel API などの API を使用してプリレンダリングされたページに伝播されますが、それが不可能な場合や、そのようなロジックが実装されるまでは、投機的読み込みをキャンセルする方が簡単です。
投機的実行ルールとコンテンツ セキュリティ ポリシー
推測ルールは <script>
要素を使用するため、JSON のみを含んでいる場合でも、サイトで script-src
Content-Security-Policy が使用されている場合は、ハッシュまたはノンスを使用して、このポリシーに含める必要があります。
script-src
に新しい inline-speculation-rules
を追加して、ハッシュまたはノンスクリプトから挿入された <script type="speculationrules">
要素をサポートできるようになりました。これは初期 HTML に含まれるルールをサポートしていないため、厳格な CSP を使用するサイトでは JavaScript によってルールを挿入する必要があります。
プリレンダリングを検出して無効にする
プリレンダリングは、ページのレンダリングを高速化(多くの場合、瞬時に)できるため、通常はユーザーにとってポジティブな体験となります。プリレンダリングされたページは、ユーザー エクスペリエンスを向上させるため、ユーザーとサイト所有者の両方にメリットがあります。
ただし、ページの初期リクエストやページで実行される JavaScript に基づいてページの状態が変化する場合など、ページのプリレンダリングを望まないこともあります。
Chrome でプリレンダリングを有効または無効にする
プリレンダリングは、chrome://settings/performance/
で [ページをプリロードする] 設定が有効になっている Chrome ユーザーに対してのみ有効になります。また、メモリ容量の少ないデバイスや、オペレーティング システムがデータセーバー モードまたは省エネモードになっている場合も、プリレンダリングは無効になります。Chrome の制限事項をご覧ください。
プリレンダリングをサーバーサイドで検出して無効にする
プリレンダリングされたページは、Sec-Purpose
HTTP ヘッダーとともに送信されます。
Sec-Purpose: prefetch;prerender
Speculation Rules API を使用してプリフェッチされたページでは、このヘッダーは prefetch
のみに設定されます。
Sec-Purpose: prefetch
サーバーはこのヘッダーに基づいて、投機的リクエストのログ記録、異なるコンテンツの返信、プリレンダリングの防止を行うことができます。成功以外の最終レスポンス コード(リダイレクト後の 200 ~ 299 の範囲外)が返された場合、ページはプリレンダリングされず、プリフェッチされたページは破棄されます。また、204 と 205 のレスポンスはプリレンダリングには無効ですが、プリフェッチには有効です。
特定のページをプリレンダリングしたくない場合は、2XX 以外のレスポンス コード(503 など)を返すのが、プリレンダリングされないようにするための最善の方法です。ただし、最適なエクスペリエンスを提供するには、事前レンダリングを許可し、ページが実際に表示されたときにのみ発生するアクションを JavaScript を使用して遅延させることをおすすめします。
JavaScript でプリレンダリングを検出する
document.prerendering
API は、ページがプリレンダリングされている間は true
を返します。ページはこれを使用して、ページが実際に有効になるまで、事前レンダリング中の特定のアクティビティを防止または遅延させることができます。
プリレンダリングされたドキュメントがアクティブになると、PerformanceNavigationTiming
の activationStart
も、プリレンダリングが開始されてからドキュメントが実際にアクティブになるまでの時間を表すゼロ以外の時間に設定されます。
次のように、プリレンダリングとプリレンダリングされたページを確認する関数を作成できます。
function pagePrerendered() { return ( document.prerendering || self.performance?.getEntriesByType?.('navigation')[0]?.activationStart > 0 ); }
ページがプリレンダリングされたかどうか(完全にプリレンダリングされたか、部分的にプリレンダリングされたか)を最も簡単に確認する方法は、ページが有効になった後に DevTools を開き、コンソールで performance.getEntriesByType('navigation')[0].activationStart
と入力することです。ゼロ以外の値が返された場合は、ページがプリレンダリングされたことがわかります。

ユーザーがページを表示してページがアクティブになると、prerenderingchange
イベントが document
でディスパッチされます。このイベントは、ページ読み込み時にデフォルトで開始されるアクティビティを有効にするために使用できます。このアクティビティは、ユーザーが実際にページを表示するまで遅延させたいものです。
これらの API を使用すると、フロントエンドの JavaScript で事前レンダリングされたページを適切に検出して処理できます。
分析への影響
アナリティクスは、ウェブサイトの利用状況を測定するために使用されます。たとえば、Google アナリティクスを使用してページビューやイベントを測定します。または、Real User Monitoring(RUM)を使用してページのパフォーマンス指標を測定します。
ページは、ユーザーが読み込む可能性が高い場合にのみプリレンダリングする必要があります。そのため、Chrome のアドレスバーのプリレンダリング オプションは、そのような可能性が高い場合(80% を超える場合)にのみ実行されます。
ただし、特に Speculation Rules API を使用する場合、プリレンダリングされたページは分析に影響を与える可能性があります。すべての分析プロバイダがデフォルトでこれを行うとは限らないため、サイト所有者は、アクティベーション時にプリレンダリングされたページでのみ分析を有効にするための追加のコードを追加する必要がある場合があります。
これは、ドキュメントがプリレンダリングされている場合は prerenderingchange
イベントを待機し、そうでない場合はすぐに解決する Promise
を使用することで実現できます。
// Set up a promise for when the page is activated, // which is needed for prerendered pages. const whenActivated = new Promise((resolve) => { if (document.prerendering) { document.addEventListener('prerenderingchange', resolve, {once: true}); } else { resolve(); } }); async function initAnalytics() { await whenActivated; // Initialise your analytics } initAnalytics();
別の方法として、ページが最初に表示されるまで分析アクティビティを遅らせることもできます。この方法では、プリレンダリングの場合と、タブがバックグラウンドで開かれる場合(右クリックして新しいタブで開くなど)の両方に対応できます。
// Set up a promise for when the page is first made visible const whenFirstVisible = new Promise((resolve) => { if (document.hidden) { document.addEventListener('visibilitychange', resolve, {once: true}); } else { resolve(); } }); async function initAnalytics() { await whenFirstVisible; // Initialise your analytics } initAnalytics();
これは分析などのユースケースでは理にかなっていますが、他のケースでは、より多くのコンテンツを読み込むことが望ましい場合もあります。そのような場合は、document.prerendering
と prerenderingchange
を使用して、プリレンダリング ページを明示的にターゲットにすることをおすすめします。
プリレンダリング中に他のコンテンツを保留する
前述の API を使用して、プリレンダリング フェーズで他のコンテンツを保留することもできます。これは、プリレンダリング ステージで実行したくない JavaScript の特定の部分やスクリプト要素全体です。
たとえば、次のスクリプトがあるとします。
<script src="https://example.com/app/script.js" async></script>
これを、前の whenActivated
関数に基づいてのみ挿入する動的に挿入されるスクリプト要素に変更できます。
async function addScript(scriptUrl) { await whenActivated; const script = document.createElement('script'); script.src = 'scriptUrl'; document.body.appendChild(script); } addScript('https://example.com/app/script.js');
これは、アナリティクスを含む個別のスクリプトを保留したり、サイト訪問中に変化する可能性のある状態やその他の変数に基づいてコンテンツをレンダリングしたりする場合に便利です。たとえば、レコメンデーション、ログイン状態、ショッピング カート アイコンなどを保留して、最新の情報を表示できるようにします。
この状況はプリレンダリングを使用した場合に発生する可能性が高いですが、前述のバックグラウンド タブで読み込まれたページにも当てはまります(そのため、whenFirstVisible
関数を whenActivated
の代わりに使用できます)。
多くの場合、状態は一般的な visibilitychange
の変更でも確認するのが理想的です。たとえば、バックグラウンドに移動したページに戻ったときに、ショッピング カートのカウンタがカート内の最新のアイテム数で更新されるようにします。これはプリレンダリング固有の問題ではなく、プリレンダリングによって既存の問題がより顕在化しているだけです。
Chrome がスクリプトや関数を手動でラップする必要性を軽減する方法の 1 つは、前述のように特定の API が保留されることです。また、サードパーティの iframe はレンダリングされないため、手動で保留する必要があるのは、この上に表示されるコンテンツのみです。
パフォーマンスの測定
パフォーマンス指標を測定する際は、ブラウザ API がレポートするページ読み込み時間ではなく、アクティベーション時間に基づいて測定する方がよいかどうかを検討する必要があります。
Chrome が Chrome ユーザー エクスペリエンス レポートを通じて測定するウェブに関する主な指標は、ユーザー エクスペリエンスを測定することを目的としています。これらは有効化時間に基づいて測定されます。たとえば、LCP が 0 秒になることが多く、ウェブに関する主な指標を改善する優れた方法であることがわかります。
バージョン 3.1.0 以降では、web-vitals
ライブラリが更新され、Chrome がコア ウェブ バイタルを測定するのと同じ方法でプリレンダリングされたナビゲーションを処理するようになりました。このバージョンでは、ページが完全にプリレンダリングされたか部分的にプリレンダリングされた場合、これらの指標のプリレンダリングされたナビゲーションを Metric.navigationType
属性でフラグ設定します。
プリレンダリングを測定する
ページがプリレンダリングされているかどうかは、PerformanceNavigationTiming
の activationStart
エントリがゼロ以外かどうかで確認できます。これは、ページビューを記録する際に、カスタム ディメンションまたは同様の機能を使用して記録できます。たとえば、前述の pagePrerendered
関数を使用します。
// Set Custom Dimension for Prerender status gtag('set', { 'dimension1': pagePrerendered() }); // Initialise GA - including sending page view by default gtag('config', 'G-12345678-1');
これにより、他のタイプのナビゲーションと比較してプリレンダリングされたナビゲーションの数をアナリティクスで確認できるようになり、パフォーマンス指標やビジネス指標をこれらのさまざまなナビゲーション タイプに関連付けることもできます。ページの読み込み速度が速いほどユーザーの満足度が高まり、導入事例でご紹介しているように、ビジネス指標に大きな影響を与えることがよくあります。
ページをプリレンダリングして瞬時のナビゲーションを実現することによるビジネス上の影響を測定することで、このテクノロジーにさらに投資してより多くのナビゲーションをプリレンダリングできるようにするか、ページがプリレンダリングされない理由を調査するかを判断できます。
ヒット率を測定する
プリレンダリング後にアクセスされたページの影響を測定するだけでなく、プリレンダリングされたものの、その後アクセスされなかったページを測定することも重要です。これは、プリレンダリングが多すぎ、ユーザーの貴重なリソースをほとんどメリットのないことに使用していることを意味する可能性があります。
これは、推測ルールが挿入されたときに(HTMLScriptElement.supports('speculationrules')
を使用してブラウザがプリレンダリングをサポートしていることを確認した後)アナリティクス イベントを発生させて、プリレンダリングがリクエストされたことを示すことで測定できます。(事前レンダリングがリクエストされたからといって、事前レンダリングが開始または完了したとは限りません。前述のとおり、事前レンダリングはブラウザへのヒントであり、ユーザー設定、現在のメモリ使用量、その他のヒューリスティックに基づいて、ページを事前レンダリングしないことを選択する場合があります)。
これらのイベントの数を、実際のプリレンダリングされたページビューと比較できます。または、比較しやすくするために、有効化時に別のイベントを配信することもできます。
この 2 つの数値の差を見ることで、「成功したヒット率」を概算できます。Speculation Rules API を使用してページをプリレンダリングしているページでは、ルールを適切に調整して、高いヒット率を維持し、ユーザーのリソースを役立てるために使用することと、不必要に使用することのバランスを保つことができます。
アドレスバーのプリレンダリングにより、推測ルールだけでなく、プリレンダリングが行われる場合があることに注意してください。これらを区別する場合は、document.referrer
(プリレンダリングされたアドレスバー ナビゲーションを含むアドレスバー ナビゲーションの場合は空白になります)を確認します。
プリレンダリングされていないページも確認してください。これらのページは、アドレスバーからでもプリレンダリングの対象外である可能性があります。この場合、パフォーマンスの改善によるメリットは得られません。Chrome チームは、プリレンダリングの対象となるかどうかをテストするための追加のツール(bfcache テストツールに似たものなど)の追加を検討しています。また、プリレンダリングが失敗した理由を公開するための API の追加も検討しています。
拡張機能への影響
Chrome 拡張機能: API を拡張してインスタント ナビゲーションをサポートに関する専用の記事で、拡張機能の作成者がプリレンダリングされたページについて考慮する必要がある追加の事項について詳しく説明しています。
フィードバック
プリレンダリングは Chrome チームによって活発に開発されており、Chrome 108 リリースで利用可能になった範囲を拡大する計画が多数あります。GitHub リポジトリまたは問題トラッカーでフィードバックをお待ちしております。また、このエキサイティングな新しい API のケーススタディをお聞かせいただき、共有できることを楽しみにしております。
関連リンク
- 投機ルールの Codelab
- 投機ルールのデバッグ
- NoState Prefetch の導入
- Speculation Rules API の仕様
- ナビゲーション投機 GitHub リポジトリ
- Chrome 拡張機能: API を拡張してインスタント ナビゲーションをサポート
謝辞
サムネイル画像: Marc-Olivier Jodoin(Unsplash)