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 プリフェッチに残りますが、将来的に廃止される予定です。

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

ページは次の 4 つの方法のいずれかでプリレンダリングできます。いずれも、ナビゲーションを高速化することを目的としています。

  1. Chrome のアドレスバー(「オムニボックス」とも呼ばれます)に URL を入力すると、Chrome は、過去の閲覧履歴に基づいて、そのページにアクセスする可能性が高いと判断した場合、そのページを自動的にプリレンダリングすることがあります。
  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 チームは、サイトに Speculation Rules を追加する手順を説明した Speculation Rules Codelab を用意しています。

熱意

対応ブラウザ

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

eagerness 設定は、推測をトリガーするタイミングを示すために使用されます。これは、ドキュメント ルールに特に便利です。

  • immediate: できるだけ早く、つまり、投機ルールが検出されたらすぐに投機を行う場合に使用します。
  • eager: immediate の設定とまったく同じように動作します。ただし今後、immediatemoderate の中間の動作が設定される予定です。
  • moderate: ユーザーがリンクにポインタを 200 ミリ秒間合わせた場合(または pointerdown イベントがそれより早く発生した場合や hover イベントのないモバイルで発生した場合)に投機を行います。
  • 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 拡張機能によって明示的にオフになっている場合も同様)。
  • バックグラウンド タブで開いたページ。

また、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 は送信されませんが、プリフェッチは試行されます。その結果、プリフェッチが無駄になり、再送信が必要になるか、さらに悪い場合はページが正しく読み込まれなくなります。

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

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 デベロッパー ツールの [要素] パネルを直接編集して <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 では、スクリプトや関数を手動でラップする必要を軽減するために、前述のように特定の API がブロックされるほか、サードパーティの iframe はレンダリングされないため、手動でブロックする必要があるのは、その上にあるコンテンツのみです。

パフォーマンスの測定

パフォーマンス指標を測定する際、アナリティクスでは、ブラウザ API が報告するページ読み込み時間ではなく、有効化時間に基づいて測定することを検討する必要があります。

Chrome ユーザー エクスペリエンス レポートで Chrome によって測定される Core Web Vitals は、ユーザー エクスペリエンスを測定することを目的としています。そのため、有効化時間に基づいて測定されます。たとえば、これにより LCP が 0 秒になる場合が多く、ウェブに関する主な指標を改善するうえで効果的な方法であることがわかります。

バージョン 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 のサムネイル画像