バックフォワード キャッシュ(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 を有効にすると、ブラウザで 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 の監視に使用される主なイベントは、ページ遷移イベントの pageshow
と pagehide
で、ほとんどのブラウザでサポートされています。
新しいページ ライフサイクル イベント(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 に入ろうとしているわけではありません。ただし、persisted
が true
であっても、ページがキャッシュされるとは限りません。ブラウザがページをキャッシュに保存することを意図しているものの、キャッシュできない要因が他にもある可能性があります。
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
イベントが発生しますが、これはブラウザがページをキャッシュに保存することを意図しているにすぎません。後で説明するさまざまな理由で、まだ破棄する必要がある場合があります。
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
イベント ハンドラを使用していないサイトでは、権限ポリシーを使用して、イベント ハンドラが追加されないようにすることができます。
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">
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">
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 から復元されると、古い情報が公開される可能性があります。
より重要なもう一つの例は、ユーザーが公共のパソコンでサイトからログアウトし、次のユーザーが [戻る] ボタンをクリックした場合です。これにより、ユーザーがログアウトしたときに消去されたはずだった個人データが漏洩する可能性があります。
このような状況を回避するには、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()
を介して制御するか、ウィンドウ オブジェクトを直接参照する必要がある場合、開いているウィンドウとオープナーは 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 を再開または再接続できます。
次の例は、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 の使用を妨げる可能性のある問題を特定できます。
ページをテストするには:
- Chrome のページに移動します。
- DevTools で、[Application] ->バックフォワード キャッシュ。
- [Run Test] ボタンをクリックします。その後、DevTools は ページを bfcache から復元できるかどうかを判断します。
テストが成功すると、パネルに「Back-フォワード キャッシュから復元されました」と表示されます。
失敗した場合は、パネルに理由が表示されます。デベロッパーが対処できる理由である場合は、パネルに [Actionable](対応可能)のマークが付きます。
この例では、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 つは、すべてのページ読み込みの指標に、それぞれのナビゲーション タイプ(navigate
、reload
、back_forward
、prerender
)でアノテーションを付けることです。これにより、全体的な分布にマイナスの偏りがある場合でも、これらのナビゲーション タイプ内でのパフォーマンスを継続的にモニタリングできます。この方法は、最初のバイトまでの時間(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 復元をサポートします。
参考情報
- Firefox のキャッシュ (Firefox では bfcache)
- ページ キャッシュ (Safari では bfcache)
- バックフォワード キャッシュ: ウェブ公開動作 (ブラウザによる bfcache の違い)
- bfcache テスター (さまざまな API やイベントがブラウザの bfcache に与える影響をテスト)
- パフォーマンス ゲーム チェンジャー: ブラウザのバック/フォワード キャッシュ (bfcache を有効にすることで Core Web Vitals が劇的に改善したことを示す Smashing Magazine のケーススタディ)