ブラウザの [戻る] ボタンと [進む] ボタンで即座に読み込まれるようにページを最適化します。
バックフォワード キャッシュ(bfcache)は、すぐに前後に移動できるブラウザの最適化です。これにより、特に低速のネットワークやデバイスを使用するユーザーのブラウジング エクスペリエンスが大幅に向上します。
ウェブ デベロッパーは、ユーザーがメリットを享受できるように、すべてのブラウザで bfcache に合わせてページを最適化する方法を理解することが重要です。
ブラウザの互換性
bfcache は、パソコンとモバイルの両方で、長年にわたって Firefox と Safari の両方でサポートされています。
Chrome バージョン 86 以降では、ごく一部のユーザーを対象に、Android のクロスサイト ナビゲーション用に bfcache が有効になっています。今後のリリースでは、追加のサポートが段階的にリリースされます。バージョン 96 以降では、パソコンとモバイルを使用するすべての Chrome ユーザーに対して bfcache が有効になっています。
bfcache の基本
bfcache は、ユーザーがページから移動するときにページの完全なスナップショット(JavaScript ヒープを含む)を保存するメモリ内キャッシュです。ページ全体をメモリ内に保持することで、ユーザーが戻ってくることを決断した場合に、ブラウザはすばやく簡単にページを復元できます。
ウェブサイトにアクセスし、リンクをクリックして別のページに移動したものの、意図したものではないことに気づいて [戻る] ボタンをクリックしたことが何回ありますか?その際に、bfcache によって前のページの読み込み速度が大きく変わります。
bfcache が無効な場合 | 前のページを読み込む新しいリクエストが開始されます。そのページが繰り返しアクセスするように 最適化されている度合いによっては、ブラウザでダウンロードしたリソースの一部(またはすべて)を再ダウンロード、再解析、再実行する必要がある場合があります。 |
bfcache が有効な場合 | 前のページの読み込みは、実質的に即時に行われます。ネットワークにアクセスしなくても、ページ全体をメモリから復元できるためです。 |
bfcache によるナビゲーションの高速化については、こちらの動画をご覧ください。
上の動画では、bfcache を含む例は、使用しない例よりもかなり高速です。
bfcache を使用すると、ナビゲーションが高速化されるだけでなく、リソースを再度ダウンロードする必要がないため、データ使用量も削減できます。
Chrome の使用状況データによると、パソコンでのナビゲーションの 10 分の 1、モバイルでの 5 分の 1 は、「戻る」または「進む」です。bfcache を有効にすると、ブラウザで毎日何十億ものウェブページを読み込む際に、データ転送と読み込みの時間を短縮できます。
「キャッシュ」の仕組み
bfcache で使用される「キャッシュ」は、HTTP キャッシュとは異なります。HTTP キャッシュは、繰り返しのナビゲーションを高速化するうえでも役立ちます。bfcache はメモリ内のページ全体(JavaScript ヒープを含む)のスナップショットですが、HTTP キャッシュには以前に行われたリクエストに対するレスポンスのみが含まれます。ページの読み込みに必要なすべてのリクエストを HTTP キャッシュから処理できることはまれであるため、bfcache による復元を使用した繰り返しアクセスは、適切に最適化された bfcache 以外のナビゲーションよりも常に高速になります。
ただし、メモリ内にページのスナップショットを作成する場合、進行中のコードの最適な保存方法に関して多少の複雑さが伴います。たとえば、ページが bfcache にある間にタイムアウトに達した setTimeout()
呼び出しをどのように処理しますか。
その答えは、ブラウザが保留中のタイマーや未解決の Promise(基本的には JavaScript タスクキュー内の保留中のタスクすべて)の実行を一時停止し、ページが bfcache から復元されたとき(または復元された場合)に処理タスクを再開することです。
タイムアウトや Promise など、リスクが非常に低い場合もありますが、混乱や予期しない動作につながる場合もあります。たとえば、IndexedDB トランザクションの一部として必要なタスクをブラウザが一時停止すると、同じオリジンで開いている他のタブに影響する可能性があります(同じ IndexedDB データベースに複数のタブで同時にアクセスできるため)。そのため、ブラウザは通常、IndexedDB トランザクションの途中でページをキャッシュに保存したり、他のページに影響する可能性がある API を使用したりすることはありません。
API のさまざまな用途がページの bfcache の利用資格に及ぼす影響について詳しくは、後述の bfcache 用にページを最適化するをご覧ください。
bfcache とシングルページ アプリ(SPA)
bfcache は、ブラウザが管理するナビゲーションで動作します。したがって、SPA 内のいわゆる「ソフト ナビゲーション」では機能しませんが、SPA の大きなセールス ポイントの一つは、そのようなナビゲーション タイプを高速にする必要があることです。ただし、SPA に戻る場合、最初からアプリを完全に再初期化するのではなく、bfcache が間違いなく役立ちます。
bfcache を監視するための API
bfcache はブラウザによって自動的に行われる最適化ですが、デベロッパーが bfcache に基づいてページを最適化し、それに応じて指標やパフォーマンス測定を調整できるように、bfcache がいつ行われるかを把握することは重要です。
bfcache の監視に使用される主なイベントは、ページ遷移イベント(pageshow
と pagehide
)です。これらのイベントは bfcache が登場する前から存在しており、現在使用されているすべてのブラウザでサポートされています。
新しいページのライフサイクル イベント(freeze
と resume
)は、ページが bfcache に出入りしたときなど、他の状況でもディスパッチされます。たとえば、CPU 使用率を最小限に抑えるためにバックグラウンドのタブがフリーズした場合などです。現在のところ、ページ ライフサイクル イベントは、Chromium ベースのブラウザでのみサポートされています。
ページが bfcache から復元されたことを確認する
pageshow
イベントは、ページが最初に読み込まれるとき、およびページが bfcache から復元されたときに、load
イベントの直後に発生します。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 に入ったタイミングを監視する
pagehide
イベントは、pageshow
イベントに相当します。pageshow
イベントは、ページが通常どおりに読み込まれたとき、または bfcache から復元されたときに発生します。pagehide
イベントは、ページが正常にアンロードされたとき、またはブラウザがページを bfcache に追加しようとしたときに呼び出されます。
pagehide
イベントにも persisted
プロパティがあり、それが false
であれば、ページが bfcache に入り込もうとしているのではないと確信できます。ただし、persisted
プロパティが true
の場合、ページがキャッシュに保存されるとは限りません。これは、ブラウザがページをキャッシュintendsものの、キャッシュできない要因が存在する可能性があることを意味します。
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.');
}
});
同様に、(イベントの persisted
プロパティが true
の場合)pagehide
イベントの直後に freeze
イベントが発生しますが、これはブラウザがページをキャッシュする意図があることを意味します。intendsただし、以下に説明するさまざまな理由で破棄が必要になることもあります。
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(サードパーティのライブラリを含む)に unload
イベント リスナーが追加された場合に警告が表示されます。
bfcache は信頼性が低く、パフォーマンスにも影響するため、Chrome では unload
イベントのサポート終了を予定しています。
権限ポリシーを使用して、ページでアンロード ハンドラが使用されないようにする
unload
イベント ハンドラを使用していないサイトでは、Chrome 115 の権限ポリシーを使用して、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?'; } });
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); });
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-cache
や Cache-Control: max-age=0
などのディレクティブは考慮されず、コンテンツがユーザーに表示される前に再検証は行われません。
ただし、bfcache の復元は即時に行われ、ページが bfcache に長時間留まることはないため、コンテンツが古くなる可能性は低いため、ユーザー エクスペリエンスは向上する可能性があります。ただし、コンテンツが分単位で変化する場合は、次のセクションで説明するように、pageshow
イベントを使用して更新を取得できます。
bfcache 復元後に古いデータや機密データを更新する
サイトでユーザーの状態(特にユーザーの機密情報)が保持されている場合は、ページを bfcache から復元した後に、そのデータを更新または消去する必要があります。
たとえば、ユーザーが購入手続きページに移動してからショッピング カートを更新した場合、古いページが bfcache から復元されると、「戻る」ナビゲーションによって古い情報が漏洩する可能性があります。
もう 1 つのより重要な例は、ユーザーが公共のパソコンでサイトからログアウトし、次のユーザーが [戻る] ボタンをクリックした場合です。これにより、ユーザーがログアウトしたときにクリアされたと想定していた個人データが漏洩する可能性があります。
このような状況を回避するには、event.persisted
が true
の場合は、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.persisted
が true
のときに pageshow
イベントの広告のみを更新すれば、ページのパフォーマンスに影響を与えずに更新できます。広告プロバイダにご確認ください。ただし、Google Publishing Tag でこれを行う方法の一例をご覧ください。
window.opener
の参照を避ける
古いブラウザでは、rel="noopener"
を指定せずに target=_blank
を含むリンクから window.open()
を使用してページを開いた場合、開始ページは開いたページの window オブジェクトへの参照を持ちます。
null 以外の window.opener
参照があるページは、セキュリティ上のリスクになるだけでなく、安全に bfcache に追加できません。アクセスを試みるページが破損する可能性があるためです。
そのため、window.opener
参照は作成しないことをおすすめします。そのためには、可能な限り rel="noopener"
を使用します(現在、これはすべての最新ブラウザでデフォルトになっています)。サイトでウィンドウを開いて window.postMessage()
で制御するか、または window オブジェクトを直接参照する必要がある場合、開いているウィンドウもオープナーも bfcache の対象になりません。
ユーザーが離れる前に、常に開いている接続を閉じる
前述のように、ページが bfcache に入ると、スケジュールされたすべての JavaScript タスクは一時停止し、ページがキャッシュから削除されたときに再開されます。
スケジュール設定された JavaScript タスクが DOM API(または現在のページだけに分離された他の API)のみにアクセスする場合、ページがユーザーに表示されないときにこれらのタスクを一時停止しても問題は生じません。
ただし、これらのタスクが、同じオリジンの他のページからもアクセスできる API(IndexedDB、Web Lock、WebSocket など)に接続されている場合、これらのタスクを一時停止すると他のタブのコードが実行されなくなる可能性があるため、問題が発生する可能性があります。
その結果、一部のブラウザでは、次のような場合にページを bfcache に保存しようとしません。
- IndexedDB 接続が開いているページ
- fetch() または XMLHttpRequest が進行中のページ
- オープンな WebSocket または WebRTC 接続のあるページ
ページでこれらの API のいずれかを使用している場合は、pagehide
イベントまたは freeze
イベント中に常に接続を閉じ、オブザーバーを削除するか切断することをおすすめします。これにより、開いている他のタブに影響するリスクなしに、ブラウザはページを安全にキャッシュできるようになります。
その後、ページが bfcache から復元されると、(pageshow
イベントまたは resume
イベントで)これらの API に再接続するか、再接続できます。
次の例は、IndexedDB を使用するときに、pagehide
イベント リスナーで開いている接続を閉じて、ページが 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 is leaving.
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 の対象にならない原因となっている問題を特定できます。
特定のページをテストするには、Chrome でそのページに移動し、DevTools で [Application] > [Back-forward Cache] に移動します。次に、[Run Test] ボタンをクリックすると、DevTools は移動を試行し、元のページを bfcache から復元できるかどうかを判断します。
成功すると、パネルに「バックフォワード キャッシュから復元されました」と表示されます。
失敗した場合は、ページが復元されなかったことと、その理由がパネルに表示されます。
デベロッパーが対処できる理由がある場合は、その旨も明記されます。
上のスクリーンショットでは、unload
イベント リスナーが使用されているため、ページが bfcache の対象になっていません。これを解決するには、unload
から pagehide
を使用するように切り替えます。
window.addEventListener('unload', ...);
window.addEventListener('pagehide', ...);
Lighthouse 10.0 では bfcache 監査も追加されました。これにより、DevTools と同様のテストを実行し、監査が失敗した場合にページが対象外となった理由を確認できます。詳しくは、bfcache 監査のドキュメントをご覧ください。
bfcache が分析やパフォーマンス測定に及ぼす影響
分析ツールでサイトへのアクセスをトラッキングしている場合は、Chrome で引き続き bfcache を有効にするユーザーが増えるため、報告されるページビュー数が減少する可能性があります。
実際、一般的な分析ライブラリのほとんどは bfcache の復元を新しいページビューとしてトラッキングしないため、bfcache を実装している他のブラウザからのページビューは、すでに過小報告されている可能性があります。
Chrome で bfcache を有効にしてもページビュー数が減らないようにするには、pageshow
イベントをリッスンして persisted
プロパティを確認することで、bfcache の復元をページビューとしてレポートできます(推奨)。
次の例は、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 は、フィールドで収集されたパフォーマンス指標、特にページの読み込み時間を測定する指標にも悪影響を及ぼす可能性があります。
bfcache のナビゲーションでは、新しいページの読み込みを開始するのではなく既存のページを復元するため、bfcache を有効にすると、収集されるページ読み込みの合計数が少なくなります。ただし、重要なのは、ページ読み込みが bfcache 復元に置き換えられたことで、データセットで最も高速なページ読み込みである可能性が高いことです。これは、「戻る」ナビゲーションと「進む」ナビゲーションは本質的にリピート アクセスであり、リピート ページの読み込みは初回訪問者のページ読み込みよりも一般的に速いためです(前述の HTTP キャッシュにより)。
その結果、データセットでのページ読み込みが高速になり、パフォーマンスが改善したとしても、分布の歪みが遅くなる可能性があります。
この問題にはいくつかの方法で対処できます。1 つは、すべてのページ読み込み指標に、それぞれのナビゲーション タイプ(navigate
、reload
、back_forward
、prerender
)でアノテーションを付ける方法です。これにより、全体的な分布が負に偏っている場合でも、これらのナビゲーション タイプ内でパフォーマンスを引き続きモニタリングできます。この方法は、最初のバイトまでの時間(TTFB)など、ユーザー中心ではないページ読み込みの指標に推奨されます。
Core Web Vitals などのユーザー中心の指標の場合は、ユーザー エクスペリエンスをより正確に表す値を報告する方が適切です。
Core Web Vitals への影響
Core Web Vitals は、さまざまな項目(読み込み速度、インタラクティビティ、視覚的な安定性)でウェブページのユーザー エクスペリエンスを測定します。bfcache による復元は従来のページの読み込みよりも高速なナビゲーションであるため、Core Web Vitals の指標にこれを反映することが重要です。結局のところ、ユーザーは bfcache が有効かどうかを気にせず、ナビゲーションが速いだけでいいのです。
Core Web Vitals の指標を収集して報告する Chrome ユーザー エクスペリエンス レポートなどのツールでは、bfcache による復元はデータセット内で個別のページアクセスとして扱われます。
また、bfcache の復元後にこれらの指標を測定するための専用のウェブ パフォーマンス API はまだありませんが、既存のウェブ API を使用して値を近似できます。
- Largest Contentful Paint(LCP)では、
pageshow
イベントのタイムスタンプと次のペイント フレームのタイムスタンプの差分を使用できます(フレーム内のすべての要素が同時にペイントされるため)。bfcache 復元の場合、LCP と FCP は同じになります。 - First Input Delay(FID)については、イベント リスナー(FID ポリフィルで使用されているのと同じもの)を
pageshow
イベントに再度追加し、FID を bfcache 復元後の初回入力の遅延としてレポートできます。 - Cumulative Layout Shift(CLS)では、現在の CLS 値を 0 にリセットするだけで、引き続き既存の Performance Observer を使用できます。
bfcache が各指標に与える影響の詳細については、Core Web Vitals の個別の指標ガイドページをご覧ください。これらの指標の bfcache バージョンをコードに実装する方法の具体例については、それらを web-vitals JS ライブラリに追加する PR をご覧ください。
参考情報
- Firefox キャッシュ (Firefox では bfcache)
- ページ キャッシュ (Safari の bfcache)
- バックフォワード キャッシュ: ウェブで公開される動作(ブラウザ間の bfcache の違い)
- bfcache テスター (さまざまな API やイベントがブラウザの bfcache にどのように影響するかをテスト)
- パフォーマンス ゲーム チェンジャー: ブラウザのバックフォワード キャッシュ (Smashing Magazine の事例で、bfcache を有効にすることで Core Web Vitals が劇的に改善されました)