Chrome でページを事前レンダリングしてページ ナビゲーションを即時に行う

対応ブラウザ

  • Chrome: 109。 <ph type="x-smartling-placeholder">
  • Edge: 109。 <ph type="x-smartling-placeholder">
  • Firefox: サポートされていません。 <ph type="x-smartling-placeholder">
  • Safari: サポートされていません。 <ph type="x-smartling-placeholder">

Chrome チームは、ユーザーが移動しそうな将来のページを完全に事前レンダリングする機能を再開しました。

事前レンダリングの歴史

これまで Chrome は <link rel="prerender" href="/next-page"> リソースヒントをサポートしていましたが、これは Chrome 以外では広くサポートされておらず、それほど表現力豊かな API ではありませんでした。

リンク rel=prerender のヒントを使用するこのような以前の事前レンダリングは非推奨となり、NoState Prefetch に置き換えられました。NoState Prefetch によって将来のページに必要なリソースが取得されますが、ページの事前レンダリングや JavaScript の実行は完全に行われませんでした。NoState Prefetch は、リソースの読み込みを改善することでページのパフォーマンスを向上させますが、完全な事前レンダリングのように即時のページ読み込みは実現しません。

Chrome チームは、Chrome に完全な事前レンダリングを再び導入しました。既存の使用方法に伴う煩雑さを回避し、将来の事前レンダリングの拡張を可能にするため、この新しい事前レンダリング メカニズムでは <link rel="prerender"...> 構文を使用しません。この構文は NoState Prefetch で引き続き有効であり、将来的に廃止される予定です。

ページの事前レンダリングの仕組み

ページの事前レンダリングは、次の 4 つの方法のいずれかで行うことができます。いずれも、より迅速なナビゲーションを実現することを目的としています。

  1. Chrome のアドレスバー(「アドレスバー」)に URL を入力すると、そのページにアクセスすることになる可能性が高い場合、過去の閲覧履歴に基づいて自動的にページが事前レンダリングされることがあります。
  2. ブックマーク バーを使用する場合、ブックマーク ボタンの上にポインタを置くと、自動的にページが事前レンダリングされることがあります。
  3. Chrome のアドレスバーに検索キーワードを入力すると、検索エンジンからの指示に応じて、検索結果ページが自動的に事前レンダリングされることがあります。
  4. サイトは Speculation Rules API を使用して、どのページを事前レンダリングするかをプログラムで Chrome に指示できます。これにより、<link rel="prerender"...> が以前使用していた機能に代わって、サイトでページ上の投機ルールに基づいて事前にページを事前レンダリングできるようになります。これらはページ上に静的に存在することも、ページ所有者が適切と判断した JavaScript によって動的に挿入されることもあります。

いずれの場合も、事前レンダリングは、非表示の背景タブでページが開かれた後に「有効」になったかのように動作しますフォアグラウンドのタブを事前レンダリングされたページに置き換えます。完全な事前レンダリングが完了する前にページが有効化された場合、現在の状態は「フォアグラウンド」になります。読み込みが継続されるため、順調にスタートできます。

事前レンダリングされたページは非表示の状態で開かれるため、煩わしい動作を引き起こす多くの API(プロンプトなど)はこの状態ではアクティブ化されず、ページがアクティブになるまで遅延します。事前レンダリングをまだ行えない少数のケースでは、事前レンダリングはキャンセルされます。Chrome チームは、事前レンダリングのキャンセルの理由を API として公開するとともに、このようなエッジケースを簡単に特定できるように DevTools の機能の強化に取り組んでいます。

事前レンダリングの影響

事前レンダリングを使用すると、次の動画に示すように、ページをほぼ瞬時に読み込むことができます。

<ph type="x-smartling-placeholder">
</ph>
事前レンダリングの影響の例

サンプルサイトはすでに高速のサイトになっていますが、それでも事前レンダリングによってユーザー エクスペリエンスが向上することがわかります。そのため、これはサイトの Core Web Vitals にも直接的な影響を及ぼします。LCP はほぼゼロになり、CLS が減少(読み込み CLS は最初の表示より前に行われるため)、INP が改善されます(ユーザーが操作する前に読み込みが完了するため)。

ページが完全に読み込まれる前にアクティブになる場合でも、ページ読み込みを先行して開始することで、読み込みエクスペリエンスを改善できます。事前レンダリングの実行中にリンクを有効にすると、事前レンダリング ページはメインフレームに移動し、読み込みが続行されます。

ただし、事前レンダリングでは追加のメモリとネットワーク帯域幅が使用されます。ユーザー リソースを犠牲にして過剰な事前レンダリングが発生しないように注意してください。事前レンダリングされるのは、ページが移動する可能性が高い場合のみです。

分析で実際にパフォーマンスに及ぼす影響を測定する方法について詳しくは、パフォーマンスの測定セクションをご覧ください。

Chrome のアドレスバーの予測機能を表示する

最初のユースケースでは、Chrome による URL の予測を chrome://predictors ページで確認できます。

<ph type="x-smartling-placeholder">
</ph> Chrome の予測ツールページで、入力したテキストに基づいて予測結果が低(グレー)、中(黄色)、高(緑)でフィルタされて表示される。
Chrome の予測ツールのページ

緑色の線は、事前レンダリングをトリガーするのに十分な信頼性があることを示します。この例では「s」と入力します信頼度(黄色)が表示されますが、「sh」と入力すると、そうすれば Chrome はほぼ確実に https://sheets.google.com に移動することになります。

このスクリーンショットは比較的新しい Chrome インストールで撮影されたもので、信頼度 0 の予測を除外しています。ただし、独自の予測子を表示すると、かなり多くのエントリが表示される可能性があり、十分な信頼度に到達するために必要な文字数も増える可能性があります。

これらの予測器は、お気づきかと思いますが、アドレスバーの推奨オプションを決定する要素でもあります。

<ph type="x-smartling-placeholder">
</ph> Chrome のアドレスバーの「予測入力」機能
アドレスバーの「予測入力」おすすめします

Chrome は入力や選択に基づいて予測子を継続的に更新します。

  • 50% を超える信頼度(黄色で表示)の場合、Chrome はドメインにプロアクティブに接続しますが、ページの事前レンダリングは行われません。
  • 信頼度が 80% を超える場合(緑色で表示)は、URL が事前レンダリングされます。

Speculation Rules API

Speculation Rules API の事前レンダリング オプションを使用すると、ウェブ デベロッパーはページに JSON 命令を挿入して、どの URL を事前レンダリングするかをブラウザに知らせることができます。

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["next.html", "next2.html"]
    }
  ]
}
</script>

または、href セレクタ(URL Pattern API に基づく)または CSS セレクタに基づいてドキュメント内で見つかったリンクを事前レンダリングするドキュメント ルール(Chrome 121 以降で利用可能)を使用すると、以下のようになります。

<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 では、サイトへの投機ルールの追加方法について説明しています。

熱意

対応ブラウザ

  • Chrome: 121。 <ph type="x-smartling-placeholder">
  • Edge: 121。 <ph type="x-smartling-placeholder">
  • Firefox: サポートされていません。 <ph type="x-smartling-placeholder">
  • Safari: サポートされていません。 <ph type="x-smartling-placeholder">

eagerness 設定は、投機機能を実行するタイミングを指定するために使用します。これは、ドキュメント ルールで特に有用です。

  • immediate: 可能な限り早く、つまり投機ルールが遵守され次第、推測に使用されます。
  • eager: これは immediate 設定と同じように動作しますが、将来的には immediate から moderate の間に配置する予定です。
  • moderate: リンクの上にポインタを 200 ミリ秒間保持すると(それより早く、hover イベントがないモバイルでは pointerdown イベントで)推測が実行されます。
  • conservative: ポインタまたはタッチダウンについて推測します。

list ルールのデフォルトの eagernessimmediate です。moderate オプションと conservative オプションを使用すると、list ルールを、ユーザーが操作する URL を特定のリストに制限できます。ただし、多くの場合は適切な where 条件を設定した document ルールを使用するほうが適切です。

document ルールのデフォルトの eagernessconservative です。ドキュメントには多数の URL が含まれる場合があるため、document ルールで immediate または eager を使用する場合は注意が必要です(次の Chrome の制限セクションもご覧ください)。

どの eagerness 設定を使用するかは、サイトによって異なります。軽量で静的なサイトの場合は、より積極的に投機するほうが費用がかからず、ユーザーにとってもメリットがあります。アーキテクチャが複雑でページ ペイロードが重いサイトでは、無駄を省くため、ユーザーから明確な意図を示すまでは推測する頻度を少なくして、無駄を減らすほうがよい場合があります。

moderate オプションは中間点であり、多くのサイトは次の投機ルールからメリットを得られます。この投機ルールでは、投機ルールの実装として、リンクの上にポインタを 200 ミリ秒間保持するか、ポインタダウン イベント時にリンクを事前レンダリングします。

<script type="speculationrules">
{
  "prerender": [{
    "where": {
      "href_matches": "/*"
    },
    "eagerness": "moderate"
  }]
}
</script>

プリフェッチ

推測ルールを使用して、完全な事前レンダリングを行わずにページをプリフェッチするだけで済みます。多くの場合、これが事前レンダリングを行うための最初の一歩となります。

<script type="speculationrules">
{
  "prefetch": [
    {
      "urls": ["next.html", "next2.html"]
    }
  ]
}
</script>

Chrome の制限

Chrome には、Speculation Rules API の過剰使用を防ぐために制限があります。

熱意 プリフェッチ Prerender(事前レンダリング)
immediate / eager 50 10
moderate / conservative 2(FIFO) 2(FIFO)
Chrome の投機的制限。

moderateconservative の設定は、ユーザーの操作に応じて、先入れ先出し(FIFO)方式で動作します。上限に達すると、新しい投機操作がキャンセルされ、最も古い投機付けによって置き換えられ、メモリを節約します。キャンセルした投機は、たとえばリンクにもう一度カーソルを合わせるなどして再度トリガーできます。その結果、その URL が再度推測され、最も古い投機が排除されます。この場合、前の投機によってその URL の HTTP キャッシュにキャッシュ可能なリソースがキャッシュされているので、もう少し時間を予測すると費用が抑えられます。そのため、上限が中程度のしきい値 2 に設定されています。静的リストルールはユーザーの操作によってトリガーされないため、ブラウザはどのルールが必要で、いつ必要かを認識できないため、上限を大きくします。

immediateeager の上限も動的であるため、list URL スクリプト要素を削除すると、削除された推測がキャンセルされ、容量が作成されます。

また、Chrome では、次のような特定の状況において投機的表現が使用されるのを防止します。

  • Save-Data
  • 省エネモード: 有効にしてバッテリー残量が少ない場合。
  • メモリの制約。
  • [ページをプリロードする]オプションが設定がオフになっている(この設定も uBlock Origin などの Chrome 拡張機能によって明示的にオフになっている)場合、
  • バックグラウンドのタブで開かれたページです。

また、事前レンダリングされたページでは、有効になるまでクロスオリジンの iframe はレンダリングされません。

これらすべての条件は、ユーザーに害を及ぼす可能性のある過剰な投機の影響を軽減することを目的としています。

ページに投機ルールを含める方法

推測ルールは、ページの HTML に静的に含めることも、JavaScript によってページに動的に挿入することもできます。

  • 静的に含まれる投機ルール: たとえば、ニュース メディアサイトやブログが最新記事を事前レンダリングする(多くのユーザーが次に移動するのが一般的である場合)。または、moderate または conservative を含むドキュメント ルールを使用して、ユーザーがリンクを操作するときに推測することもできます。
  • 動的に挿入される投機ルール: アプリのロジック、ユーザーに合わせた推測、その他のヒューリスティックなどに基づいて行われます。

過去に多くのライブラリが <link rel=prefetch> を使用して行ったように、リンクにカーソルを合わせたり、クリックしたりするなどのアクションに基づく動的挿入を優先する場合は、ドキュメント ルールを確認することをおすすめします。これにより、ブラウザはさまざまなユースケースに対応できます。

投機ルールは、メインフレームの <head> または <body> に追加できます。サブフレーム内の投機ルールは適用されず、事前レンダリングされたページの投機ルールは、そのページがアクティブになってから適用されます。

Speculation-Rules HTTP ヘッダー

対応ブラウザ

  • Chrome: 121。 <ph type="x-smartling-placeholder">
  • Edge: 121。 <ph type="x-smartling-placeholder">
  • Firefox: サポートされていません。 <ph type="x-smartling-placeholder">
  • Safari: サポートされていません。 <ph type="x-smartling-placeholder">

ソース

推測ルールは、ドキュメントの HTML に直接含める代わりに、Speculation-Rules HTTP ヘッダーを使用して送信することもできます。これにより、ドキュメントの内容自体を変更することなく、CDN によるデプロイが簡単になります。

ドキュメントとともに返され、投機ルールを含む JSON ファイルの場所を指す Speculation-Rules HTTP ヘッダーです。

Speculation-Rules: "/speculationrules.json"

このリソースは、正しい MIME タイプを使用する必要があり、クロスオリジン リソースの場合は、CORS チェックに合格する必要があります。

Content-Type: application/speculationrules+json
Access-Control-Allow-Origin: *

相対 URL を使用する場合は、推測ルールに "relative_to": "document" キーを含めることができます。それ以外の場合、相対 URL は投機ルールの JSON ファイルの URL を基準とします。この方法は、一部(またはすべて)の同一オリジンのリンクを選択する必要がある場合に特に便利です。

投機ルールと SPA

推測ルールは、ブラウザが管理するフルページ ナビゲーションでのみサポートされており、シングルページ アプリ(SPA)ページや App Shell ページではサポートされていません。このアーキテクチャでは、ドキュメントの取得は利用されず、データやページの API または部分的な取得が行われ、処理されて現在のページに表示されます。いわゆる「ソフト ナビゲーション」に必要なデータは、投機ルール以外ではアプリでプリフェッチできますが、事前レンダリングはできません。

投機ルールを使用して、前のページからアプリケーション自体を事前レンダリングできます。これにより、一部の SPA で発生する初期読み込みの追加コストを相殺できます。ただし、アプリ内でルートの変更を事前にレンダリングすることはできません。

投機ルールをデバッグする

この新しい API の表示とデバッグに役立つ Chrome DevTools の新機能については、投機ルールのデバッグに関する専用の投稿をご覧ください。

複数の投機ルール

同じページに複数の投機ルールを追加して、既存のルールに追加することもできます。したがって、次のような場合は one.htmltwo.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>

対応ブラウザ

  • Chrome: 121。 <ph type="x-smartling-placeholder">
  • Edge: 121。 <ph type="x-smartling-placeholder">
  • Firefox: サポートされていません。 <ph type="x-smartling-placeholder">
  • Safari: サポートされていません。 <ph type="x-smartling-placeholder">

ソース

ページのプリフェッチまたは事前レンダリングを行う場合、特定の URL パラメータ(技術的には「検索パラメータ」)は、サーバーによって実際に配信されるページにとって重要ではなく、クライアントサイドの JavaScript でのみ使用される場合があります。

たとえば、UTM パラメータは Google アナリティクスでキャンペーンの測定に使用されますが、通常、サーバーから異なるページが配信されることはありません。つまり、page1.html?utm_content=123page1.html?utm_content=456 はサーバーから同じページを配信するため、キャッシュから同じページを再利用できます。

同様に、クライアントサイドでしか処理されない他の URL パラメータもアプリケーションで使用できます。

No-Vary-Search プロポーザルでは、配信されるリソースとの間に差異が生じないパラメータをサーバーが指定できるため、それらのパラメータのみが異なるドキュメントの以前にキャッシュされたバージョンをブラウザで再利用できます。これは、Chrome(および Chromium ベースのブラウザ)でプリフェッチ ナビゲーションの推測を行うためにサポートされています(ただし、事前レンダリングでもサポートする予定です)。

推測ルールでは、No-Vary-Search HTTP ヘッダーが返される場所を示すために expects_no_vary_search を使用できます。これにより、不要なダウンロードをさらに防ぐことができます。

<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>

この例では、商品 ID 123124 の両方で、/products の最初のページの HTML は同じです。ただし、最終的には、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 ヘッダーが含まれていることを認識し、プリフェッチが完了するまで待機できます。

投機ルールの制限と今後の機能強化

投機ルールの対象は、同じタブ内で開かれたページに限られますが、Google はこうした制限を減らすよう取り組んでいます

デフォルトでは、投機は同一オリジンのページに制限されます。同一サイトのクロスオリジン ページでの推測(たとえば、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 が存在する場合、推測はトリガーされず、DevTools にエラーが表示されます。

現在の制限を踏まえて、可能な限り内部リンクと外部リンクの両方についてユーザー エクスペリエンスを改善するパターンの一つとして、同一オリジンの URL を事前レンダリングし、クロスオリジン URL をプリフェッチしてみるのが挙げられます。

<script type="speculationrules">
  {
    "prerender": [
      {
        "where": { "href_matches": "/*" },
        "eagerness": "moderate"
      }
    ],
    "prefetch": [
      {
        "where": { "not": { "href_matches": "/*" } },
        "eagerness": "moderate"
      }
    ]
  }
</script>

セキュリティ上、クロスオリジン リンクに対するクロスオリジン予測をデフォルトで防止するための制限が必要となります。これは、Cookie を送信せずにプリフェッチを試みるクロスオリジン デスティネーションに対する <link rel="prefetch"> の改善です。これにより、無駄なプリフェッチが発生し、再送信が必要となり、さらに悪いことに、間違ったページ読み込みが発生します。

Service Worker によって制御されるページのプリフェッチでは、推測ルールはサポートされていません。Google は、このようなサポートを追加できるよう取り組んでいます。最新情報については、Service Worker に関する問題のサポートをご覧ください。Service Worker で制御されるページでは、事前レンダリングがサポートされています。

Detect 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 DevTools の [Elements] パネルを直接編集して <script type = "speculationrules"> 要素を追加しても、投機ルールが登録されません。代わりに、これを DOM に動的に追加するスクリプトをコンソールから実行して、ルールを挿入する必要があります。

タグ マネージャーから投機ルールを追加する

Google タグ マネージャー(GTM)などのタグ マネージャーを使用して投機ルールを追加するには、前述と同じ理由により、<script type = "speculationrules"> 要素を GTM で直接追加するのではなく、JavaScript を使用して挿入する必要があります。

<ph type="x-smartling-placeholder">
</ph> Google タグ マネージャーでのカスタム HTML タグの設定
Google タグ マネージャーによる推測ルールの追加

GTM では const がサポートされていないため、この例では var を使用しています。

投機ルールをキャンセル

投機ルールを削除すると事前レンダリングはキャンセルされますが、事前レンダリングが行われる頃には、事前レンダリングを開始するためのリソースがすでに消費されている可能性が高いため、事前レンダリングのキャンセルが必要になる可能性がある場合は、事前レンダリングを行わないことをおすすめします。

投機ルールとコンテンツ セキュリティ ポリシー

投機ルールでは <script> 要素を使用するため、JSON のみが含まれていても、サイトでこれを使用する場合は、ハッシュまたはノンスを使用して script-src Content-Security-Policy に含める必要があります。

新しい inline-speculation-rulesscript-src に追加すると、ハッシュスクリプトまたはノンス スクリプトから挿入された <script type="speculationrules"> 要素をサポートできます。これは最初の HTML に含まれるルールに対応していないため、厳格な CSP を使用しているサイトでは JavaScript によってルールを挿入する必要があります。

事前レンダリングを検出して無効にする

事前レンダリングを使用すると、ページをすばやく(多くの場合はすぐに)レンダリングできるため、通常はユーザーにとって快適なエクスペリエンスになります。事前レンダリングされたページでは、他の方法では実現が困難なユーザー エクスペリエンスが提供されるため、ユーザーとサイト所有者の双方にとってメリットがあります。

ただし、ページの事前レンダリングを行わない場合もあります。たとえば、最初のリクエストや、ページで実行されている JavaScript に基づいてページの状態が変更された場合などです。

Chrome で事前レンダリングを有効または無効にする

事前レンダリングは、「ページをプリロードする」権限がある Chrome ユーザーに対してのみ有効になりますchrome://settings/performance/ で設定します。また、メモリが少ないデバイスの場合、またはオペレーティング システムが [データを保存] モードまたは [省エネ] モードの場合も、事前レンダリングが無効になります。Chrome の制限をご覧ください。

サーバーサイドの事前レンダリングを検出して無効にする

事前レンダリングされたページは、Sec-Purpose HTTP ヘッダーとともに送信されます。

Sec-Purpose: prefetch;prerender

Speculation Rules API を使用してプリフェッチされたページでは、このヘッダーが prefetch のみに設定されます。

Sec-Purpose: prefetch

サーバーはこのヘッダーに基づいて応答し、投機リクエストをログに記録したり、別のコンテンツを返したり、事前レンダリングを阻止したりできます。不成功のレスポンス コード(200 や 304 以外)が返された場合、ページは事前レンダリングされず、プリフェッチ ページは破棄されます。

特定のページが事前レンダリングされないようにするには、それが最善の方法です。ただし、最適な動作を実現するためには、JavaScript を使用して、代わりに事前レンダリングを許可し、ページが実際に表示されるときにのみ行う必要があるアクションを遅らせることをおすすめします。

JavaScript で事前レンダリングを検出する

ページの事前レンダリング中は、document.prerendering API から true が返されます。これは、ページが実際に有効になるまで、事前レンダリング中の特定のアクティビティを防止または遅らせるために使用できます。

事前レンダリングされたドキュメントが有効になると、PerformanceNavigationTimingactivationStart もゼロ以外の時間に設定されます。これは、事前レンダリングが開始されてからドキュメントが実際に有効化されるまでの時間を表します。

次のように、事前レンダリングページと事前レンダリングされたページを確認する関数を用意できます。

function pagePrerendered() {
  return (
    document.prerendering ||
    self.performance?.getEntriesByType?.('navigation')[0]?.activationStart > 0
  );
}

ページが(全体または部分的に)事前レンダリングされたかどうかを確認するには、ページがアクティブになった後に DevTools を開き、コンソールで「performance.getEntriesByType('navigation')[0].activationStart」と入力します。ゼロ以外の値が返された場合、そのページは事前レンダリングされています。

<ph type="x-smartling-placeholder">
</ph> ページが事前レンダリングされたことを示す、正の値の activationStart を示す Chrome DevTools のコンソール
コンソールで事前レンダリングをテストする。
で確認できます。

ユーザーがページを閲覧していると、prerenderingchange イベントが document でディスパッチされます。これにより、それまではページの読み込み時にデフォルトで開始され、ユーザーが実際にページを表示するまで遅らせるアクティビティを有効にできます。

これらの API を使用すると、フロントエンド JavaScript が事前レンダリングされたページを適切に検出し、処理を行うことができます。

分析への影響

アナリティクスは、たとえば Google アナリティクスを使用してページビューやイベントを測定するなど、ウェブサイトの利用状況を測定するために使用されます。または、Real User Monitoring(RUM)を使用してページのパフォーマンス指標を測定します。

ユーザーがページを読み込む可能性が高い場合にのみ、ページを事前レンダリングする必要があります。そのため、Chrome のアドレスバーの事前レンダリング オプションは、確率が非常に高い(80% 以上の確率)場合にのみ表示されます。

ただし、特に Speculation Rules API を使用する場合は、事前レンダリングされたページがアナリティクスに影響する可能性があります。すべてのアナリティクス プロバイダがデフォルトでそうしているわけではないため、サイト所有者は、アクティベーション時に事前レンダリングされたページのアナリティクスのみを有効にするために、コードの追加が必要になることがあります。

そのためには、Promise を使用します。これは、ドキュメントが事前レンダリングされている場合は prerenderingchange イベントを待機し、ドキュメントが事前レンダリングされている場合は直ちに解決されます。

// 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.prerenderingprerenderingchange を使用して、特に事前レンダリング ページをターゲットにすることをおすすめします。

事前レンダリング中は他のコンテンツを保留する

前述したのと同じ 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');

これは、分析を含む個別のスクリプトを抑制する場合や、訪問中に変化する可能性がある状態やその他の変数に基づいてコンテンツをレンダリングする場合に役立ちます。たとえば、おすすめ情報、ログイン状態、買い物かごアイコンなどを常に表示して、常に最新の情報を表示できます。

事前レンダリングを使用するとこの問題が頻繁に発生する可能性がありますが、前述のバックグラウンド タブで読み込まれたページにもこのような条件が適用されます(そのため、whenActivated の代わりに whenFirstVisible 関数を使用できます)。

多くの場合、一般的な visibilitychange の変更についても状態を確認することが理想的です。たとえば、バックグラウンドのページに戻ったとき、買い物かごカウンターをカート内の最新の数で更新する必要があります。したがって、これは事前レンダリングに固有の問題ではなく、事前レンダリングによって既存の問題がより明らかになるだけです。

Chrome では、スクリプトや関数を手動でラップする必要性を軽減する 1 つの方法が、前述のように特定の API を保持し、サードパーティの iframe はレンダリングされないため、手動で保持する必要があるのは上のコンテンツのみであることです。

パフォーマンスの測定

パフォーマンス指標を測定する場合は、ブラウザ API が報告するページ読み込み時間ではなく、アクティベーション時間に基づいて測定した方がよいかどうかを検討する必要があります。

Core Web Vitals(Chrome で Chrome ユーザー エクスペリエンス レポートを使用して測定)は、ユーザー エクスペリエンスを測定することを目的としています。そのため、これらは有効化日時に基づいて測定されます。その結果、たとえば LCP が 0 秒に短縮され、Core Web Vitals を改善する優れた方法であることがわかります。

バージョン 3.1.0 以降、web-vitals ライブラリが更新され、Chrome で Core Web Vitals を測定するのと同じ方法で事前レンダリングされたナビゲーションを処理するようになりました。このバージョンでは、ページ全体または一部が事前レンダリングされた場合、Metric.navigationType 属性でこれらの指標の事前レンダリングされたナビゲーションも報告されます。

事前レンダリングを測定する

ページが事前レンダリングされるかどうかは、activationStart のゼロ以外のエントリ PerformanceNavigationTiming で確認できます。これはその後、カスタム ディメンションを使用して、または同様の方法でページビューをログに記録できます(前述の 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 リポジトリへのフィードバックや、Issue Tracker のご利用をお待ちしております。また、この新しい API の事例紹介をぜひお聞かせください。

謝辞

Marc-Olivier Jodoin 氏によるサムネイル画像(Unsplash より)