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

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

ウェブ デベロッパーは、ユーザーが bfcache のメリットを享受できるように、bfcache 向けにページを最適化する方法を理解することが重要です。

ブラウザの互換性

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

bfcache の基本

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

ウェブサイトにアクセスして別のページへのリンクをクリックしたものの、目的のページではなかったため「戻る」ボタンをクリックした経験はありますか?このとき、bfcache は前のページの読み込み速度に大きな影響を与えます。

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

バックフォワード キャッシュの動作を説明する動画をご覧ください。ナビゲーションの高速化についてご理解いただけると思います。

bfcache を使用すると、戻る / 進むナビゲーションでページの読み込みが大幅に高速化されます。

動画では、bfcache を使用した例は、使用していない例よりもかなり高速です。

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

Chrome の使用状況データによると、パソコンでのナビゲーションの 10 回に 1 回、モバイルでのナビゲーションの 5 回に 1 回は、戻るまたは進むの操作です。bfcache を有効にすると、ブラウザは毎日数十億ものウェブページのデータ転送と読み込み時間を削減できます。

「キャッシュ」の仕組み

bfcache で使用される「キャッシュ」は、リピート ナビゲーションの高速化に独自の役割を果たす HTTP キャッシュとは異なります。bfcache は JavaScript ヒープを含むメモリ内のページ全体のスナップショットですが、HTTP キャッシュには以前に作成されたリクエストのレスポンスのみが含まれています。ページを読み込むために必要なすべてのリクエストが HTTP キャッシュから満たされることはほとんどないため、バックフォワード キャッシュ復元を使用した再訪問は、最適化されたバックフォワード キャッシュ以外のナビゲーションよりも常に高速です。

ページをフリーズして後で再度有効にするには、進行中のコードを最適に保存する方法という点で複雑さがあります。たとえば、ページが bfcache にある間にタイムアウトに達した setTimeout() 呼び出しをどのように処理しますか?

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

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

さまざまな API の使用状況がページの bfcache の対象にどのように影響するかについて詳しくは、bfcache 向けにページを最適化するをご覧ください。

bfcache と iframe

ページに埋め込み iframe が含まれている場合、iframe 自体は bfcache の対象にはなりません。たとえば、iframe 内の別の URL に移動した場合、前のコンテンツは bfcache に保存されません。戻ると、ブラウザはメインフレームではなく iframe 内で「戻る」ことになりますが、iframe 内の戻るナビゲーションでは bfcache は使用されません。

ただし、メインフレームが bfcache から復元されると、埋め込まれた iframe は、ページが bfcache に入ったときの状態として復元されます。

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

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

bfcache はブラウザで管理されるナビゲーションで動作するため、シングルページ アプリ(SPA)内の「ソフト ナビゲーション」では動作しません。ただし、SPA に戻る際に、アプリを最初から完全に再初期化するのではなく、bfcache を利用することで、パフォーマンスを改善できます。

bfcache を監視する API

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

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

新しいページ ライフサイクル イベント(freezeresume)も、ページが bfcache に入るときや 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 の対象となる(または対象とならない)ページの条件を理解することが重要です。

以降のセクションでは、ブラウザでページがキャッシュに保存される可能性を最大限に高めるためのベスト プラクティスについて説明します。

unload イベントは使用しない

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

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(サードパーティ ライブラリの JavaScript を含む)が unload イベント リスナーを追加すると、デベロッパーに警告します。

信頼性が低く、bfcache のパフォーマンスに影響を与えるため、Chrome では unload イベントの非推奨化を検討しています。

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

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

Permissions-Policy: unload=()

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

beforeunload リスナーは条件付きで追加する

beforeunload イベントは、最新のブラウザの 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 キャッシュに保存しないようブラウザに指示します。ログインが必要なページなど、ユーザーの機密情報を含むリソースに使用されます。

バックフォワード キャッシュは HTTP キャッシュではありませんが、これまで、Cache-Control: no-store が(サブリソースではなく)ページリソース自体に設定されている場合、ブラウザはページをバックフォワード キャッシュに保存しないことを選択してきました。そのため、Cache-Control: no-store を使用するページはバックフォワード キャッシュの対象にならない可能性があります。プライバシーを保護する形で 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() を使用してページを開くと、開いたページの window オブジェクトへの参照が、開いたページに設定されていました。

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 を再度開くか、再接続できます。

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

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

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

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

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)でアノテーションを付ける方法です。これにより、全体的な分布が負の方向に偏っていても、これらのナビゲーション タイプ内のパフォーマンスを継続的にモニタリングできます。このアプローチは、Time to First Byte(TTFB)など、ユーザー中心ではないページの読み込み指標におすすめします。

ウェブに関する主な指標などのユーザー中心の指標については、ユーザーが体験した内容をより正確に表す値を報告する方が望ましいです。

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 の復元をサポートしています。

参考情報