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 を入力すると、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>

または、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 チームは、サイトに投機ルールを追加する手順を説明した 投機ルールの 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 ミリ秒間保持するか、ポインタダウン イベント時にリンクを事前レンダリングします。

<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 にエラーが表示されます。

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

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

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

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

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 を使用して挿入する必要があります。

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 Jodoin 氏によるサムネイル画像(Unsplash より)