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

バックフォワード キャッシュ(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 から復元された場合はタスクの処理を再開します。

タイムアウトやプロミスの場合など、リスクは比較的低い場合もありますが、混乱や予期しない動作につながることもあります。たとえば、ブラウザが 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 が行われるかを把握しておくことが重要です。

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 をサポートしているブラウザでは、resume イベントは、ページが bfcache から復元されたとき(pageshow イベントの直前)と、ユーザーがフリーズしたバックグラウンド タブに再度アクセスしたときに呼び出されます。ページの状態をフリーズ後に更新する場合(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 イベント リスナーを追加すると、デベロッパーに警告します。

信頼性が低く、bfcache のパフォーマンスに影響するため、Chrome では unload イベントのサポートを終了する予定です。

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

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

Permissions-Policy: unload=()

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

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

beforeunload イベントは、最新のブラウザではページを 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 デベロッパー ツールでは、ページをテストして、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 の復元をサポートしています。

参考情報