バックフォワード キャッシュ

バックフォワード キャッシュ(bfcache)は、ブラウザを [戻る]と [次へ]のナビゲーションですブラウジング体験が大幅に向上し 特にネットワークやデバイスが遅い場合です

ウェブ デベロッパーにとって、bfcache を使用するためにページを最適化する方法を理解しておくことは、ユーザーにメリットをもたらすことです。

ブラウザの互換性

bfcache は、パソコンとモバイルの両方で長年にわたって FirefoxSafari の両方でサポートされてきました。

Chrome バージョン 86 以降、ごく一部のユーザーに対して Android でのクロスサイト ナビゲーション用に bfcache が有効になりました。その後のリリースでは、追加のサポートが徐々に展開されてきました。バージョン 96 以降では、パソコンとモバイルのすべての Chrome ユーザーに対して bfcache が有効になっています。

bfcache の基本

bfcache はメモリ内キャッシュで、ユーザーの移動時にページの完全なスナップショット(JavaScript ヒープを含む)が保存されます。ページ全体をメモリに残しておくことで、ブラウザはユーザーが戻ろうとした際にページをすぐに復元できます。

ウェブサイトにアクセスして、リンクをクリックして別のページに移動したが、意図したものでないことに気づいて [戻る] ボタンをクリックしたことは何回ありますか?この時点で、bfcache を使用すると、前のページの読み込み速度に大きな違いが生まれます。

bfcache が有効になっていない 前のページを読み込むための新しいリクエストが開始されます。そのページが再訪問用にどれだけ 最適化されているかによっては、ダウンロードしたリソースの一部(またはすべて)をブラウザで再ダウンロード、再解析、再実行しなければならない場合があります。
bfcache を有効にした場合 前のページは基本的に瞬時に読み込まれます。ネットワークに接続することなく、メモリからページ全体を復元できるためです。

こちらの動画では、bfcache の実際の活用方法が紹介されており、ナビゲーションの高速化に役立ちます。

<ph type="x-smartling-placeholder">
</ph>
bfcache を使用すると、前後移動時にページの読み込みが大幅に速くなります。

この動画では、bfcache が含まれているサンプルが、使用しないサンプルよりもかなり高速になります。

bfcache を使用すると、ナビゲーションを高速化できるだけでなく、リソースを再度ダウンロードする必要がないため、データ使用量も削減できます。

Chrome の使用状況データによると、パソコンでのナビゲーションの 10 人に 1 回、モバイルでは 5 人に 1 回が「前へ」または「進む」となっています。bfcache を有効にすると、ブラウザで 1 日に何十億ものウェブページを読み込むためのデータ転送や読み込み時間を削減できます。

「キャッシュ」が作品

「キャッシュ」bfcache によって使用される HTTP キャッシュ とは異なります。HTTP キャッシュは、繰り返しの移動を高速化するうえで独自の役割を果たします。bfcache はメモリ内のページ全体のスナップショット(JavaScript ヒープを含む)ですが、HTTP キャッシュには以前に行われたリクエストに対するレスポンスのみが含まれます。ページの読み込みに必要なすべてのリクエストが HTTP キャッシュから処理されることは非常にまれであるため、bfcache による復元を使用した再訪問は、適切に最適化された bfcache 以外のナビゲーションよりも常に高速です。

しかし、メモリ内にページのスナップショットを作成するには、進行中のコードを保存する最適な方法という点で多少複雑になります。たとえば、ページが bfcache 内にあるときにタイムアウトに達した setTimeout() 呼び出しをどのように処理すればよいでしょうか。

その場合、ブラウザは、JavaScript タスクキュー内のほぼすべての保留中のタスクを含め、bfcache 内のページの保留中のタイマーや未解決の Promise をすべて一時停止し、ページが bfcache から復元されるとタスクの処理を再開します。

タイムアウトや Promise などの一部のケースでは、このリスクは非常に低いものの、混乱や予期しない動作につながる可能性があります。たとえば、IndexedDB の処理の一部として必要なタスクをブラウザが一時停止した場合です。 トランザクションの場合、同じオリジンで開いている他のタブに影響する可能性があります。これは、同じ IndexedDB データベースに複数のタブから同時にアクセスできるためです。そのため、ブラウザは通常、IndexedDB トランザクションの最中や、他のページに影響する可能性のある API の使用中にページをキャッシュしようとしません。

さまざまな API の使用状況がページの bfcache の利用資格に与える影響について詳しくは、bfcache 用にページを最適化するをご覧ください。

bfcache と iframe

ページに埋め込み iframe がある場合、iframe 自体は bfcache の対象になりません。たとえば、iframe 内の別のページに移動して戻ると、ブラウザは「戻る」bfcache を使用しません。ただし、iframe 内の「戻る」ナビゲーションでは bfcache を使用しません。

bfcache をブロックする API が埋め込み iframe で使用されている場合は、メインフレームでも bfcache を使用できないことがあります。これを回避するには、メインフレームに設定されている権限ポリシーまたは sandbox 属性を使用します。

bfcache とシングルページ アプリ(SPA)

bfcache はブラウザ管理のナビゲーションで機能するため、「ソフト ナビゲーション」では機能しません。シングルページアプリ(SPA)内でただし、SPA に戻るときには、最初からアプリを完全に初期化し直すよりも bfcache が役に立ちます。

bfcache を監視する API

bfcache はブラウザが自動的に最適化する機能ですが、それに合わせてページを最適化し、それに応じて指標やパフォーマンス測定を調整できるように、デベロッパーがいつ発生するかを把握しておくことは依然として重要です。

bfcache の監視に使用される主なイベントは、ページ遷移イベントpageshowpagehide で、ほとんどのブラウザでサポートされています。

新しいページ ライフサイクル イベント(freeze および resume)は、ページが bfcache に出入りするときだけでなく、CPU 使用率を最小限に抑えるためにバックグラウンド タブがフリーズした場合など、その他の状況でもディスパッチされます。これらのイベントは、Chromium ベースのブラウザでのみサポートされています。

ページが bfcache から復元されるタイミングを監視する

pageshow イベントは、ページが最初に読み込まれるときに load イベントの直後、およびページが bfcache から復元されるたびに発生します。pageshow イベントには persisted プロパティが含まれます。ページが bfcache から復元された場合は true、それ以外の場合は false になります。persisted プロパティを使用して、通常のページ読み込みと bfcache による復元を区別できます。例:

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    console.log('This page was restored from the bfcache.');
  } else {
    console.log('This page was loaded normally.');
  }
});

Page Lifecycle API をサポートするブラウザでは、ページが bfcache から復元されたとき(pageshow イベントの直前)と、ユーザーがフリーズしたバックグラウンド タブに再度アクセスしたときに、resume イベントが発生します。固定されたページの状態(bfcache 内のページを含む)を更新する場合は resume イベントを使用できますが、サイトの bfcache のヒット率を測定する場合は pageshow イベントを使用する必要があります。場合によっては両方を使用する必要があります。

bfcache の測定に関するベスト プラクティスについて詳しくは、bfcache が分析とパフォーマンスの測定に与える影響をご覧ください。

ページが bfcache に追加されたタイミングを確認する

pagehide イベントは、ページがアンロードされたとき、またはブラウザがページを bfcache に入れようとしたときに呼び出されます。

pagehide イベントにも persisted プロパティがあります。false であれば、そのページは bfcache に入ろうとしているわけではありません。ただし、persistedtrue であっても、ページがキャッシュされるとは限りません。ブラウザがページをキャッシュに保存することを意図しているものの、キャッシュできない要因が他にもある可能性があります。

window.addEventListener('pagehide', (event) => {
  if (event.persisted) {
    console.log('This page *might* be entering the bfcache.');
  } else {
    console.log('This page will unload normally and be discarded.');
  }
});

同様に、persistedtrue の場合、pagehide イベントの直後に freeze イベントが発生しますが、これはブラウザがページをキャッシュに保存することを意図しているにすぎません。後で説明するさまざまな理由で、まだ破棄する必要がある場合があります。

bfcache 用にページを最適化する

すべてのページが bfcache に保存されるわけではなく、ページが bfcache に保存されていても無期限に保持されるわけではありません。キャッシュ ヒット率を最大化するには、ページが bfcache の対象となる(および対象外である)理由を理解することが重要です。

以下のセクションでは、ブラウザがページをキャッシュできる可能性をできるだけ高くするためのベスト プラクティスについて概説します。

unload イベントを使用しない

すべてのブラウザで bfcache を最適化する最も重要な方法は、unload イベントを使用しないことです。いつだって!

unload イベントは bfcache よりも前から存在しており、インターネット上の多くのページが、unload イベントの発生後はページが存続しないという(妥当な)前提のもとで運用されるため、ブラウザにとって問題となります。しかし、こうしたページの多くは、ユーザーが別のページへ移動するたびに unload イベントが発生するという前提で構築されているため、課題となります。この前提はもはや真実ではありません(また、長い間、そうではなかった)。

そのため、ブラウザはジレンマに直面しています。ユーザー エクスペリエンスを改善できるものを選択しなければなりませんが、同時にページが壊れてしまうリスクもあります。

パソコンでの Chrome と Firefox では、unload リスナーを追加した場合、ページが bfcache の対象から外れています。リスクは低くなりますが、多くのページが対象から除外されます。Safari は unload イベント リスナーを使用して一部のページをキャッシュに保存しようとしますが、不具合が発生する可能性を減らすために、ユーザーがページから移動しているときは unload イベントを実行しないため、イベントの信頼性は極めて低くなります。

モバイルでは、Chrome と Safari は unload イベント リスナーを使用してページをキャッシュに保存しようとします。モバイルでは unload イベントが常に極めて信頼性が低いため、破損のリスクは低いためです。Firefox では、unload を使用しているページは bfcache の対象にならないものとして扱われます。ただし、iOS ではすべてのブラウザで WebKit レンダリング エンジンを使用する必要があるため、Safari と同様に動作します。

unload イベントの代わりに、pagehide イベントを使用してください。pagehide イベントは、unload イベントが発生するすべてのケースで発生します。また、ページが bfcache に追加されたときにも呼び出されます。

実際、Lighthouse には no-unload-listeners 監査があり、ページ上の JavaScript(サードパーティ ライブラリの JavaScript を含む)のいずれかが unload イベント リスナーを追加した場合に警告が表示されます。

Chrome では、信頼性が低く、bfcache がパフォーマンスに及ぼす影響を考慮して、unload イベントのサポート終了を予定しています。

権限ポリシーを使用して、ページでアンロード ハンドラが使用されないようにする

unload イベント ハンドラを使用していないサイトでは、Chrome 115 の権限ポリシーを使用して、イベント ハンドラが追加されないようにすることができます。

Permission-Policy: unload()

また、サードパーティや拡張機能によってアンロード ハンドラが追加され、サイトが bfcache の対象にならないようにすることで、サイトの速度低下を防ぐこともできます。

条件付きで beforeunload リスナーのみを追加する

beforeunload イベントによってページが bfcache の対象となり、最新のブラウザでは bfcache を使用できなくなることはありませんが、以前は bfcache であったため、まだ信頼できません。どうしても必要な場合を除き、このイベントの使用は避けてください。

ただし、unload イベントとは異なり、 beforeunload。たとえば、Google Chat のメッセージ履歴が 保存していない変更内容はユーザーが ページを離れると失われますこの例では、 beforeunload リスナーは、ユーザーが保存されていない場合にのみ追加することをおすすめします。 保存していない変更が保存されたら直ちに削除する。

すべきでないこと
window.addEventListener('beforeunload', (event) => {
  if (pageHasUnsavedChanges()) {
    event.preventDefault();
    return event.returnValue = 'Are you sure you want to exit?';
  }
});
<ph type="x-smartling-placeholder"></ph> このコードは、beforeunload リスナーを無条件に追加します。
すべきこと
function beforeUnloadListener(event) {
  event.preventDefault();
  return event.returnValue = 'Are you sure you want to exit?';
};

// A function that invokes a callback when the page has unsaved changes.
onPageHasUnsavedChanges(() => {
  window.addEventListener('beforeunload', beforeUnloadListener);
});

// A function that invokes a callback when the page's unsaved changes are resolved.
onAllChangesSaved(() => {
  window.removeEventListener('beforeunload', beforeUnloadListener);
});
<ph type="x-smartling-placeholder"></ph> このコードは、必要な場合にのみ beforeunload リスナーを追加します( 含まれていないときは削除されます)。

Cache-Control: no-store の使用を最小限に抑える

Cache-Control: no-store は、ウェブサーバーがレスポンスに設定できる HTTP ヘッダーで、レスポンスを HTTP キャッシュに保存しないようにブラウザに指示します。ログインが必要なページなど、機密性の高いユーザー情報を含むリソースに使用されます。

bfcache は HTTP キャッシュではありませんが、従来は(サブリソースではなく)ページリソース自体に Cache-Control: no-store が設定されている場合、ブラウザはページを bfcache に保存しないように選択していました。現在、プライバシー保護の手法で Chrome のこの動作を変更する取り組みが進行中ですが、現時点では Cache-Control: no-store を使用しているページはすべて bfcache の対象ではありません。

Cache-Control: no-store はページの bfcache の使用を制限するため、機密情報を含むページで設定し、いかなる種類のキャッシュ保存も適切でないものにしてください。

常に最新のコンテンツを提供する必要があり、コンテンツに機密情報が含まれていないページの場合は、Cache-Control: no-cache または Cache-Control: max-age=0 を使用します。これらのディレクティブは、コンテンツを配信する前にコンテンツを再検証するようにブラウザに指示します。ページの bfcache の適格性には影響しません。

ページが bfcache から復元される場合、そのページは HTTP キャッシュではなくメモリから復元されることに注意してください。そのため、Cache-Control: no-cacheCache-Control: max-age=0 などのディレクティブは考慮されず、コンテンツがユーザーに表示される前に再検証は行われません。

ただし、bfcache による復元は即時に行われ、ページが bfcache に長期間留まることはないため、コンテンツが古くなっている可能性は低いため、ユーザー エクスペリエンスは向上する可能性があります。ただし、コンテンツが分単位で変更される場合は、次のセクションで説明するように、pageshow イベントを使用して更新を取得できます。

bfcache による復元後に古いデータやセンシティブ データを更新する

サイトでユーザーの状態(特にユーザーの機密情報)が保持されている場合は、ページが bfcache から復元された後に、そのデータを更新または消去する必要があります。

たとえば、ユーザーが購入手続きページに移動してからショッピング カートを更新した場合、「戻る」ナビゲーションによって古いページが bfcache から復元されると、古い情報が公開される可能性があります。

より重要なもう一つの例は、ユーザーが公共のパソコンでサイトからログアウトし、次のユーザーが [戻る] ボタンをクリックした場合です。これにより、ユーザーがログアウトしたときに消去されたはずだった個人データが漏洩する可能性があります。

このような状況を回避するには、event.persistedtrue の場合に、pageshow イベント後にページを常に更新することをおすすめします。

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Do any checks and updates to the page
  }
});

コンテンツをそのまま更新するのが理想的ですが、変更によっては強制的に完全に再読み込みすることをおすすめします。次のコードは、pageshow イベントでサイト固有の Cookie が存在するかどうかを確認し、見つからなかった場合は再読み込みします。

window.addEventListener('pageshow', (event) => {
  if (event.persisted && !document.cookie.match(/my-cookie)) {
    // Force a reload if the user has logged out.
    location.reload();
  }
});

再読み込みを行うと、履歴が保持されるという利点があります(これにより前方ナビゲーションが可能になりますが、リダイレクトの方が適切な場合もあります)。

広告と bfcache による復元

「戻る」ナビゲーションや「次へ」ナビゲーションのたびに新しい広告セットを配信するために bfcache の使用は避けたくなるかもしれません。しかし、そのような行為がパフォーマンスに影響するだけでなく、広告のエンゲージメントの向上につながるかどうかも疑問です。ユーザーは、再びクリックするつもりだった広告を bfcache から復元せず再読み込みしてクリックできなかったことに気付いたことがあるかもしれません。仮説を立てる前に、このシナリオをテストすることが重要です(A/B テストで行うのが理想的です)。

bfcache の復元時に広告を更新する必要があるサイトでは、event.persistedtrue のときに pageshow イベントで広告のみを更新すると、ページのパフォーマンスに影響を与えることなく更新できます。ご利用の広告プロバイダにご確認ください。ただし、Google Publishing Tag でこれを行う方法の一例はこちらをご覧ください。

window.opener 参照を避ける

古いブラウザでは、rel="noopener" を指定せずに target=_blank のリンクから window.open() を使用してページを開いた場合、開始ページには開いたページの window オブジェクトへの参照が含まれていました。

null 以外の window.opener 参照を含むページは、セキュリティ上のリスクとなるだけでなく、bfcache に入れても安全ではありません。アクセスしようとするページが破損する可能性があるためです。

そのため、window.opener 参照は作成しないことをおすすめします。そのためには、可能な限り rel="noopener" を使用します(現在、すべての最新ブラウザではこれがデフォルトになっています)。サイトでウィンドウを開き、window.postMessage() を介して制御するか、ウィンドウ オブジェクトを直接参照する必要がある場合、開いているウィンドウとオープナーは bfcache の対象になりません。

ユーザーが移動する前に開いている接続を閉じる

前述のように、ページが bfcache に追加されると、スケジュールされた JavaScript タスクがすべて一時停止され、ページがキャッシュから取り出された時点で再開されます。

これらのスケジュールされた JavaScript タスクが、DOM API(または現在のページだけに隔離されているその他の API)にのみアクセスする場合、ページがユーザーに表示されない間、これらのタスクを一時停止しても問題は発生しません。

ただし、これらのタスクが同じオリジンの他のページからもアクセスできる API に接続されている場合(IndexedDB、Web Lock、WebSocket など)、これらのタスクを一時停止すると他のタブのコードが実行されなくなる可能性があるため、問題が発生する可能性があります。

そのため、次のような場合は一部のブラウザでは bfcache にページを配置できません。

ページでこれらの API のいずれかを使用している場合は、pagehide または freeze イベント中に接続を閉じて、オブザーバーを削除または切断することを強くおすすめします。これにより、開いている他のタブに影響を与えることなく、ブラウザがページを安全にキャッシュできます。

ページが bfcache から復元されたら、pageshow または resume イベント中にそれらの API を再開または再接続できます。

次の例は、pagehide イベント リスナーで開いている接続を閉じることで、IndexedDB を使用しているページが bfcache の対象であることを確認する方法を示しています。

let dbPromise;
function openDB() {
  if (!dbPromise) {
    dbPromise = new Promise((resolve, reject) => {
      const req = indexedDB.open('my-db', 1);
      req.onupgradeneeded = () => req.result.createObjectStore('keyval');
      req.onerror = () => reject(req.error);
      req.onsuccess = () => resolve(req.result);
    });
  }
  return dbPromise;
}

// Close the connection to the database when the user leaves.
window.addEventListener('pagehide', () => {
  if (dbPromise) {
    dbPromise.then(db => db.close());
    dbPromise = null;
  }
});

// Open the connection when the page is loaded or restored from bfcache.
window.addEventListener('pageshow', () => openDB());

ページがキャッシュ可能であることを確認するテストを実施する

Chrome DevTools を使用すると、ページが bfcache 向けに最適化されていることをテストし、bfcache の使用を妨げる可能性のある問題を特定できます。

ページをテストするには:

  1. Chrome のページに移動します。
  2. DevTools で、[Application] ->バックフォワード キャッシュ
  3. [Run Test] ボタンをクリックします。その後、DevTools は ページを bfcache から復元できるかどうかを判断します。
で確認できます。 <ph type="x-smartling-placeholder">
</ph> DevTools のバックフォワード キャッシュ パネル
DevTools の [Back-forward Cache] パネル。

テストが成功すると、パネルに「Back-フォワード キャッシュから復元されました」と表示されます。

<ph type="x-smartling-placeholder">
</ph> ページが bfcache から正常に復元されたと DevTools が報告する
ページが正常に復元された。

失敗した場合は、パネルに理由が表示されます。デベロッパーが対処できる理由である場合は、パネルに [Actionable](対応可能)のマークが付きます。

<ph type="x-smartling-placeholder">
</ph> DevTools で bfcache からページを復元できないという報告
実行可能な結果を伴う bfcache テストの失敗

この例では、unload イベント リスナーを使用しているため、ページが bfcache の対象ではなくなります。これを修正するには、unload から pagehide を使用するように切り替えます。

すべきこと
window.addEventListener('pagehide', ...);
すべきでないこと
window.addEventListener('unload', ...);

Lighthouse 10.0 では、同様のテストを実行する bfcache 監査も追加されました。詳細については、bfcache 監査のドキュメントをご覧ください。

bfcache が分析とパフォーマンスの測定に与える影響

分析ツールを使用してサイトへのアクセスを測定している場合、Chrome で bfcache がより多くのユーザーに対して有効になると、レポートされるページビューの総数が減少することがあります。

実際、bfcache を実装している他のブラウザからのページビューはすでに過少に報告されている可能性があります。一般的な分析ライブラリの多くは、bfcache の復元を新しいページビューとして測定していないためです。

bfcache による復元をページビュー数に含めるには、pageshow イベントのリスナーを設定し、persisted プロパティを確認します。

次の例は、Google アナリティクスでこの処理を行う方法を示しています。他の分析ツールも同様のロジックを使用する可能性があります。

// Send a pageview when the page is first loaded.
gtag('event', 'page_view');

window.addEventListener('pageshow', (event) => {
  // Send another pageview if the page is restored from bfcache.
  if (event.persisted) {
    gtag('event', 'page_view');
  }
});

bfcache のヒット率を測定する

また、bfcache が使用されているかどうかを測定すると、bfcache を使用していないページを特定できます。ページ読み込みのナビゲーション タイプを測定することで測定できます。

// Send a navigation_type when the page is first loaded.
gtag('event', 'page_view', {
   'navigation_type': performance.getEntriesByType('navigation')[0].type;
});

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Send another pageview if the page is restored from bfcache.
    gtag('event', 'page_view', {
      'navigation_type': 'back_forward_cache';
    });
  }
});

back_forward ナビゲーションと back_forward_cache ナビゲーションのカウントを使用して、bfcache のヒット率を計算します。

「戻る」または「戻る」ナビゲーションで bfcache が使用されないシナリオは、サイト所有者の判断の及ばないものもあると認識しておくことが重要です。以下に例を示します。

  • ユーザーがブラウザを終了して再起動したとき
  • ユーザーがタブを複製したとき
  • ユーザーがタブを閉じて再度開いたとき

場合によっては、一部のブラウザで元のナビゲーション タイプが保持され、「戻る/早送り」ナビゲーションでなくても back_forward のタイプが表示される場合があります。

これらの除外があっても、メモリを節約するために一定期間経過後に bfcache は破棄されます。

そのため、ウェブサイトの所有者は back_forward のすべてのナビゲーションで bfcache のヒット率が 100% になるとは限りません。ただし、ページ自体が bfcache の使用を妨げているページ(前後移動の割合が高いページ)を特定するには、この比率の測定が有用です。

Chrome チームが NotRestoredReasons API を追加して、ページで bfcache が使用されない理由を明らかにすることで、デベロッパーは bfcache のヒット率を改善できます。また、Chrome チームは CrUX にナビゲーション タイプを追加し、bfcache のナビゲーション数をご自身で測定しなくても確認できるようにしました。

パフォーマンスの測定

bfcache は、フィールドで収集されたパフォーマンス指標、特にページの読み込み時間を測定する指標に悪影響を及ぼすこともあります。

bfcache によるナビゲーションでは、新しいページの読み込みが開始されるのではなく既存のページが復元されるため、bfcache を有効にすると、収集されるページ読み込みの総数が少なくなります。しかし重要なのは、ページ読み込みが bfcache による復元で置き換えられる場合、おそらくデータセット内で最も高速なページ読み込みになるということです。これは、前後のナビゲーションは定義上、リピート訪問であり、繰り返しページ読み込みは通常、初回訪問者によるページ読み込みよりも速いためです(前述の HTTP キャッシュにより)。

その結果、データセットの高速ページ読み込みが減少し、分布の歪みが遅くなる可能性があります(ユーザーのパフォーマンスは向上しているかもしれません)。

この問題に対処する方法はいくつかあります。1 つは、すべてのページ読み込みの指標に、それぞれのナビゲーション タイプnavigatereloadback_forwardprerender)でアノテーションを付けることです。これにより、全体的な分布にマイナスの偏りがある場合でも、これらのナビゲーション タイプ内でのパフォーマンスを継続的にモニタリングできます。この方法は、最初のバイトまでの時間(TTFB)など、ユーザー中心ではないページ読み込みの指標におすすめします。

Core Web Vitals のようなユーザー中心の指標については、ユーザー エクスペリエンスをより正確に表している値を報告することをおすすめします。

Core Web Vitals への影響

Core Web Vitals は、さまざまな項目(読み込み速度、インタラクティビティ、視覚的な安定性)でウェブページに関するユーザー エクスペリエンスを測定します。bfcache の復元では、ページ全体の読み込みよりも高速のナビゲーションになるため、Core Web Vitals の指標にこの点を反映させることが重要です。結局のところ、ユーザーは bfcache が有効かどうかに関係なく、ナビゲーションが高速であることだけを気にしています。

Chrome ユーザー エクスペリエンス レポートなど、Core Web Vitals の指標を収集してレポートするツールでは、bfcache による復元はデータセット内の個別のページ訪問として処理されます。また、bfcache の復元後にこれらの指標を測定するための専用のウェブ パフォーマンス API はありませんが、既存のウェブ API を使用して値を概算できます。

  • Largest Contentful Paint(LCP)の場合は、pageshow イベントのタイムスタンプと次にペイントされるフレームのタイムスタンプの差分を使用します。これは、フレーム内のすべての要素が同時にペイントされるためです。bfcache による復元の場合、LCP と FCP は同じです。
  • [Interaction to Next Paint (INP)] では、既存の Performance Observer を引き続き使用しますが、現在の INP 値を 0 にリセットします。
  • Cumulative Layout Shift(CLS)の場合は、既存の Performance Observer を引き続き使用し、現在の CLS 値を 0 にリセットします。

bfcache が各指標に与える影響について詳しくは、個々の Core Web Vitals の指標ガイドのページをご覧ください。これらの指標の bfcache バージョンを実装する方法の具体例については、PR でこれらの指標を web-vitals JS ライブラリに追加するをご覧ください。

web-vitals JavaScript ライブラリは、レポートする指標の bfcache 復元をサポートします。

参考情報