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

バックフォワード キャッシュ(bfcache)は、前のページと次のページにすぐに移動できるようにブラウザを最適化する機能です。この機能を使うと、特にネットワーク速度やデバイスの動作が遅い環境で、ユーザーのブラウジング体験が大幅に向上します。

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

ブラウザの互換性

すべての主要ブラウザには bfcache が含まれています(Chrome バージョン 96 以降、FirefoxSafari など)。

bfcache の基本

バックフォワード キャッシュ(bfcache)では、ユーザーが他のページに移動したときにページを破棄するのではなく、破棄を延期して JS の実行を一時停止します。ユーザーがすぐに戻ってきた場合、ページは再び表示され、JS の実行が一時停止されなくなります。これにより、ユーザーはページ ナビゲーションをほぼ瞬時に行うことができます。

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

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

bfcache の動作を示す動画で、ナビゲーションの高速化効果を確認できます。

bfcache を使用すると、前後移動時にページの読み込みが大幅に速くなります。

この動画では、bfcache を使用する例が、使用しない例よりもかなり高速です。

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

Chrome の使用状況データによると、パソコンでは 10 回に 1 回、モバイルでは 5 回に 1 回、前後に移動しています。bfcache を有効にすると、ブラウザで毎日何十億ものウェブページを読み込むためのデータ転送や時間を削減できます。

「キャッシュ」の仕組み

bfcache で使用される「キャッシュ」は、繰り返しのナビゲーションを高速化するために独自の役割を果たす 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 内の別のページに移動した後で戻ると、ブラウザはメインフレーム内ではなく iframe 内に戻りますが、iframe 内の「戻る」ナビゲーションでは bfcache は使用されません。

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

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

bfcache はブラウザ管理のナビゲーションに対応しているため、シングルページ アプリ(SPA)内の「ソフト ナビゲーション」には対応していません。ただし、アプリを最初から完全に再初期化するのではなく、SPA に戻る場合は、bfcache が役に立ちます。

bfcache をモニタリングする API

bfcache はブラウザが自動的に行う最適化ですが、デベロッパーがそのタイミングを把握して、ページを最適化し、指標やパフォーマンス測定を調整できるようにすることが重要です。

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

新しいページ ライフサイクル イベント(freezeresume)は、ページが 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 の場合、freeze イベントは pagehide イベントの直後に発生しますが、これはブラウザがページをキャッシュに保存することを意図していることを意味するだけです。ただし、後述するいくつかの理由により、破棄しなければならない場合もあります。

ページを bfcache 向けに最適化する

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

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

unload イベントは使用しない

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

unload イベントは bfcache より前のものであり、インターネット上の多くのページは、unload イベントがトリガーされた後にページが存在しなくなるという(合理的な)前提で動作するため、ブラウザにとって問題となります。これらのページの多くは、ユーザーが離脱するたびに unload イベントがトリガーされることを前提に作成されているため、これは課題となります。これはもはや事実ではなく(長い間事実ではありませんでした)、

そのため、ブラウザはジレンマに直面しています。ユーザー エクスペリエンスを向上させる方法と、ページが破損するリスクがある方法のどちらかを選択する必要があります。

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

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

unload イベントの代わりに、pagehide イベントを使用してください。pagehide イベントは、unload イベントが呼び出されたときと、ページが bfcache に保存されたときに必ず呼び出されます。

実際、Lighthouse には no-unload-listeners 監査があり、ページ上の JavaScript(サードパーティ ライブラリのものを含む)が unload イベント リスナーを追加すると、デベロッパーに警告します。

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

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

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

Permission-Policy: unload=()

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

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

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

ただし、unload イベントとは異なり、beforeunload には正当な用途があります。たとえば、ページを離れると保存されていない変更が失われることをユーザーに警告する場合などです。この場合、ユーザーが保存されていない変更を行った場合にのみ beforeunload リスナーを追加し、保存されていない変更が保存された直後に削除することをおすすめします。

すべきでないこと
window.addEventListener('beforeunload', (event) => {
  if (pageHasUnsavedChanges()) {
    event.preventDefault();
    return event.returnValue = 'Are you sure you want to exit?';
  }
});
このコードは、無条件で 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);
});
このコードは、必要な場合にのみ beforeunload リスナーを追加します(不要な場合は削除します)。

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

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

bfcache は HTTP キャッシュではありませんが、これまで、Cache-Control: no-store がページ リソース自体に設定されている場合(サブリソースではなく)、ブラウザはページを bfcache に保存しないように選択していたため、Cache-Control: no-store を使用するページは bfcache の対象外となる可能性があります。プライバシーを保護しながらChrome のこの動作を変更する作業が進められています。

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 が存在するかどうかを確認し、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 パブリッシャー タグを使用した方法の例をご確認ください。

window.opener 参照を避ける

以前のブラウザでは、rel="noopener" を指定せずに target=_blank を含むリンクから window.open() を使用してページを開くと、開いたページのウィンドウ オブジェクトへの参照が開いたページに存在していました。

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

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

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

前述のように、ページが bfcache に保持されると、スケジュールされたすべての JavaScript タスクが一時停止し、ページがキャッシュから削除されると再開されます。

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

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

そのため、一部のブラウザでは、次のシナリオでページを bfcache に保存しようとしません。

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

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

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

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 で、[アプリケーション] > [バックフォワード キャッシュ] に移動します。
  3. [Run Test] ボタンをクリックします。その後、DevTools はページを離れて再度戻ることにより、bfcache からページを復元できるかどうかを判断します。
DevTools のバックフォワード キャッシュ パネル
DevTools の [バックフォワード キャッシュ] パネル。

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

ページが bfcache から正常に復元されたことを DevTools が報告している
正常に復元されたページ。

失敗した場合は、パネルに理由が表示されます。デベロッパーが対処可能な理由の場合は、[対処可能] と表示されます。

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 チームは、ページが bfcache を使用しない場合の理由を特定できる NotRestoredReasons API を追加しました。これにより、デベロッパーは bfcache のヒット率を改善できます。また、Chrome チームは CrUX にナビゲーション タイプを追加し、自分で測定せずに bfcache ナビゲーションの数を確認できるようにしました。

パフォーマンスの測定

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

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

その結果、データセット内の高速ページ読み込みが減り、ユーザーが経験するパフォーマンスは向上しているにもかかわらず、分布がより遅くなる可能性があります。

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

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

Core Web Vitals への影響

ウェブに関する主な指標は、さまざまなディメンション(読み込み速度、インタラクティビティ、視覚的安定性)でウェブページのユーザー エクスペリエンスを測定します。ユーザーは bfcache の復元をページ全体の読み込みよりも高速なナビゲーションとして認識するため、ウェブに関する主な指標でこれを反映することが重要です。ユーザーは 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 バージョンを実装する方法の具体的な例については、web-vitals JS ライブラリに追加する PR をご覧ください。

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

参考情報