bfcacheとは

bfcache は、back/forward cache の略で、ブラウザのキャッシュ機能のひとつです。

bfcache は、ウェブページの完全なスナップショットをJavaScriptの実行状況も含めてメモリに保存します。そして、ブラウザの戻るボタンや進むボタン(スマートフォンではスワイプによる戻る/進むも含む)によって、ページが遷移すると、そのページはメモリに保存された bfcache をもとに表示されます。ウェブページをネットワークを介してリクエストせずに表示できるため、高速にページを表示できます。

よく見かける例に、次のようなものが挙げられます。

スマートフォンサイトのドロワーメニューを開いた状態で、別のページに移動した後、スワイプして前のページに戻るとドロワーが開いたままになっている。

この現象は多くの場合 bfcache によってページが表示されているためだと考えられます。

こちらの動画もご覧ください。

bfcache が有効化どうかを確認する方法

Chromeのデベロッパーツールで、Application > Back/forward cache の画面に表示される test back/forward cache ボタンをクリックして、Successfully served from back/forward cache. と表示されれば、そのページは bfcache が有効になっている事を意味します。


Chromeのデベロッパーツールのbfcacheの確認画面

Chromeのデベロッパーツールでbfcacheの有効・無効を確認できる

bfcache の無効のページと、有効のページの、ページの表示のされ方を比較しましたので、以下の動画もご覧ください。

bfcache が有効の場合は、戻る/進むボタンでページを移動すると、ページ自体がリクエストされていない事が分かります。

なお、この動画は、Chromeのシークレットモードでキャプチャしています。

サポートしているブラウザ

bfcache は、元々はFirefoxやSafariでサポートされていた機能ですが、現在はChromeをはじめ主要なブラウザがサポートしているようです。

基本的には、 ページ内に unload イベントリスナーが存在する場合を除いて、bfcache は動作しないようですが、この挙動は各ブラウザによって異なります。

例えば、前述の動画で bfcache が無効だったページを、Firefoxで表示すると bfcache によってページが表示されている事が確認できます。

bfcache によるページ表示を検知して特定の処理を行う方法

bfcache を元にページが表示されると、JavaScriptも、そのページを離れた時点の段階から再開されます。オブジェクトの状態も保持されるようです。

そのため、ページロード時に必ず何らかの処理を行いたい場合などは、 bfcache を使ってほしくない時があります。

その場合は、 Cache-Control: no-store を適用する事で、ページが bfcache に保存されなくなります。

Cache-Control: no-store は 情報を HTTP cache に保存しないという指示で、 bfcache に対する指示ではないようですが、このHTTPヘッダーがセットされると、ブラウザは ページをbfcache に保存しないようにしてきたようです。そういう歴史があると、 web.dev の記事で紹介されていました。

詳しくはこちらの記事をご覧ください。

Source : Back/forward cache  |  Articles  |  web.dev

ただ、 私が経験した事例では、iOS Safariの場合は、 Cache-Control: no-store を適用したページでも bfcache が有効になっていました。そのため、iOSアプリのアプリ内ブラウザ(webview)でも同様の現象が起きていました。

この場合は、bfcache が有効な場合は、ページをリロードさせるという処理を行う事で対策を行いました。

bfcache が有効かどうかは、以下のコードでチェックします。

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // do something if page loaded from bfcache
  }
});

persisted プロパティは、ページがキャッシュからロードされた場合に true を返すため、これを利用します。

なお、persisted プロパティについて、前述の web.dev では、bfcache からページが復元された場合に true を返すと書いてある一方で、 MDN では、単に、キャッシュからページがロードされている場合に true を返すと解説されていて、厳密に bfcache とは言及されていませんでした。

Source : PageTransitionEvent: persisted property - Web APIs | MDN

なお、(恐らく)Safari以外では Cache-Control: no-store がセットされていれば、 event.persistedfalse になるため ifブロック 内のコードは実行されません。


執筆者情報
Profile Icon

ウェブ&マーケティングディレクター

清水公太

Web、映像、雑誌などの制作現場で、企画、デザイン、撮影、コーディング、マーケティング、業務改善などを経験してきました。 守備範囲は広めの雑食性のディレクターです。