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

対応ブラウザ

  • Chrome: 109.
  • Edge: 109。
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

Chrome チームは、ユーザーが次に移動する可能性が高いページの完全なプリレンダリングを復活させました。

プリレンダリングの簡単な歴史

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

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

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 の機能を強化して、このようなエッジケースを簡単に特定できるように取り組んでいます。

事前レンダリングの影響

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

プリレンダリングの影響の例。

サンプルサイトはすでに高速なサイトですが、それでもプリレンダリングによってユーザー エクスペリエンスがどのように改善されるかを確認できます。そのため、サイトのCore Web Vitals にも直接影響し、LCP がゼロに近づき、CLS が減少します(読み込み CLS は最初のビューの前に発生するため)。また、INP も改善されます(ユーザーが操作する前に読み込みが完了する必要があるため)。

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

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

アナリティクスで実際のパフォーマンスへの影響を測定する方法について詳しくは、パフォーマンスの測定のセクションをご覧ください。

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

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

入力したテキストに基づいて、低(グレー)、中(アンバー)、高(緑)の予測が表示されるようにフィルタされた Chrome 予測ページ。
Chrome 予測ページ

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

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

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

Chrome アドレスバーの「予測入力」機能
アドレスバーの「予測入力」機能

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 Pattern 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 チームは、サイトに投機ルールを追加する手順を説明した 投機ルールの Codelab を用意しています。

熱意

対応ブラウザ

  • Chrome: 121。
  • Edge: 121.
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

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 ミリ秒間保持したとき、または pointerdown イベントでリンクをプリレンダリングします。

<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。
  • Edge: 121.
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

ソース

推測ルールは、ドキュメントの 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 を基準とします。この方法は、一部(またはすべて)の同一オリジンのリンクを選択する必要がある場合に特に便利です。

推測ルールと SPA

推測ルールは、ブラウザによって管理されるフルページ ナビゲーションでのみサポートされます。シングルページ アプリ(SPA)やアプリシェル ページではサポートされません。このアーキテクチャでは、ドキュメントの取得は使用せず、データの 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。
  • Edge: 121。
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

ソース

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

たとえば、UTM パラメータは Google アナリティクスでキャンペーンの測定に使用されますが、通常はサーバーから異なるページが配信されることはありません。つまり、page1.html?utm_content=123page1.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 123124 の両方で同じです。ただし、最終的には、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 ヘッダーが含まれることがブラウザに通知され、そのプリフェッチが完了するまで待機できます。

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

推測ルールは同じタブ内で開いたページに制限されていますが、この制限を緩和するための取り組みを進めています

デフォルトでは、推測は同一オリジンのページに制限されます。同一サイトのクロスオリジン ページの推測(例: https://a.example.comhttps://b.example.com のページをプリレンダリングする)。これを使用するには、推測対象のページ(この例では https://b.example.com)で Supports-Loading-Mode: credentialed-prerender HTTP ヘッダーを含めてオプトインする必要があります。オプトインしないと、Chrome は推測をキャンセルします。

今後のバージョンでは、事前レンダリングされたページに Cookie が存在せず、事前レンダリングされたページが同様の Supports-Loading-Mode: uncredentialed-prerender HTTP ヘッダーでオプトインしている限り、同一サイト以外のクロスオリジン ページの事前レンダリングも許可される可能性があります。

推測ルールはすでにクロスオリジン プリフェッチをサポートしていますが、クロスオリジン ドメインの Cookie が存在しない場合のみです。以前にそのサイトにアクセスしたユーザーの Cookie が存在する場合、推測はトリガーされず、DevTools にエラーが表示されます。

現在の制限事項を考慮すると、内部リンクと外部リンクの両方でユーザー エクスペリエンスを改善できるパターンの 1 つは、同一オリジンの URL を事前レンダリングし、クロスオリジンの URL をプリフェッチすることです。

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

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

Speculate ルールは、サービス ワーカーによって制御されるページのプリフェッチではサポートされていません。Google では、このサポートを追加できるよう取り組んでいます。最新情報については、サービス ワーカーに関する問題のサポートをご覧ください。プリレンドは、サービス ワーカーが制御するページでサポートされています。

Detect Speculation Rules API をサポート

Speculation Rules API のサポートは、標準の HTML チェックで検出できます。

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)などのタグ管理システムを使用して推測ルールを追加するには、前述の理由により、GTM から <script type = "speculationrules"> 要素を直接追加するのではなく、JavaScript を使用して挿入する必要があります。

Google タグ マネージャーのカスタム HTML タグの設定
Google タグ マネージャーで推定ルールを追加する。

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

推測ルールをキャンセルする

推測ルールを削除すると、プリレンダリングがキャンセルされますが、その時点ではプリレンダリングの開始にリソースがすでに消費されている可能性があります。そのため、プリレンダリングをキャンセルする必要がある可能性がある場合は、プリレンダリングを使用しないことをおすすめします。

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

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

新しい inline-speculation-rulesscript-src に追加して、ハッシュまたはノンス付きスクリプトから挿入された <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 を返します。ページで使用すると、ページが実際に有効になるまで、事前レンダリング中に特定のアクティビティを防止または遅らせることができます。

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

次のようにして、プリレンダリングプリレンダリング済みのページを確認する関数を作成できます。

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

ページが(完全にまたは部分的に)プリレンダリングされたかどうかを確認する最も簡単な方法は、ページが有効になった後に DevTools を開き、コンソールに performance.getEntriesByType('navigation')[0].activationStart と入力することです。ゼロ以外の値が返された場合は、ページがプリレンダリングされたことを意味します。

ページが事前レンダリングされたことを示す、正の値の activationStart を示す Chrome DevTools のコンソール
コンソールで事前レンダリングをテストします。

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

これらの 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.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 が報告するページの読み込み時間ではなく、有効化時間に基づいて測定することを検討する必要があります。

Chrome ユーザー エクスペリエンス レポートで Chrome によって測定される Core Web Vitals は、ユーザー エクスペリエンスを測定することを目的としています。そのため、有効化時間に基づいて測定されます。その結果、たとえば 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 JodoinUnsplash のサムネイル画像