👋

ブラウザの「戻る」で通信が走らない...? Cache-Control: no-storeとbfcache

に公開

⚠️⚠️⚠️
本記事で出てくる「戻るボタン」ってのはchromeの左上にある戻るボタンです。
ブラウザバックってやつです。
⚠️⚠️⚠️

ことの発端: 戻るボタンを押した時の挙動がおかしい。。。

ある日、ちょっとしたフォームをPOSTする処理を書いていて、

「ンンンンン?戻るボタン押したときの挙動がおかしいな…」

ページを戻っても、サーバーにリクエストが飛ばない。

なのに、画面の状態がそのまま復元されてるっぽい。

「え、ブラウザってそんなことするの?」ってなって、軽く混乱。

後日この話を会社のメンターにしたら、

cache-control とか bfcache あたり見てみるといいかもね〜」

と、コメントをもらった。

今回は、cache-control: no-storebfcache がどんな関係なのか を、実際に検証しながら整理していきます。

用語の調査

まずは、 cache-controlbfcacheがそれぞれ何をしているのかを整理してみます。

名前は知ってたけど、挙動をちゃんと理解してなかったので、そのあたりから。

cache-controlってなんなんだ?

MDN曰く

HTTP の Cache-Control は、キャッシュをブラウザーや共有キャッシュ(プロキシーや CDN など)において制御するためのディレクティブ(指示)です。

らしい。

ふーーーむ。わからん。

ChatGPTとちょっとお話しして、以下の理解に落ち着いた。

レスポンスの内容を毎回サーバーから取得したら遅いから、それを再利用したい。この再利用の仕方をコントロールするのが Cache-Control ってことですね。

メンターからは「 cache-control: no-store から一回試してみるといいかもねえ」とコメントをいただいたので本記事ではこれを試してみます。

cache-control: no-store ってなーに?

MDN曰く

no-store は、あらゆる種類のキャッシュがこのレスポンスを保存しないようにすることを指示します。

ふむ。とりあえず、cacheしたくない!時はこれを使うのがいいのかな?

bfcache(Back-Forward Cache)ってなに?

MDNの説明をざっくりとまとめると、

bfcache(バック・フォワード・キャッシュ)は、
ブラウザの「戻る」「進む」を高速化するために、ページの“スナップショット”を丸ごと保存しておく仕組み。

ふむなるほど、、、

ん???

どっちもページの内容をcacheしてる??同じことを違う言葉で言ってる??

cache-controlとbfcacheの違い

こんな感じの違いがあるらしい。

比較項目 Cache-Control bfcache(Back-Forward Cache)
目的 リロードや再訪問時の通信制御 ブラウザの「戻る」「進む」で高速復帰するため
保存するもの HTTPレスポンスの “リソースのコピー”(HTML・CSS・JSなど) ページ全体の実行状態(DOM・JS・スクロール位置・フォーム入力・JS実行スタックまで含む)
保存場所 ディスク or メモリ メモリ(プロセス内)
持続時間 秒~時間~日など設定次第 短時間だけ。タブを閉じたりメモリ不足で消える
Cache-Controlで制御可能? ✅ 可能 ❌ 基本的に制御不可(no-store 指定でも bfcache に入ることがある)
再リクエストは? no-store や有効期限切れならサーバーへ再取得 bfcache復帰時はサーバーへリクエストしない(復元だけ)

なるほど、Cache-Control はHTTPの話、bfcache はブラウザの内部最適化。
レイヤーが違うってことですね。

検証

なんとなーーーーく理解したので、実際ローカルで検証。

Railsで簡単なページを作って、cache-control の設定を変えながら
戻るボタンを押したときの挙動を確認しました。

cache-controlを指定しない

まずは何も指定しないデフォルト状態から。

Networkタブを確認してみると、cache-controlは以下のように設定されていた。(Railsのデフォルト設定っぽい)

max-age=0, private, must-revalidate

ざっくり意味を整理すると:

  • max-age=0 → キャッシュしていいけど、すぐ期限切れ扱いにする
  • private → ブラウザだけでキャッシュしてOK(CDNやプロキシではダメ)
  • must-revalidate → キャッシュを使う前に必ずサーバーに確認しろ

つまり、「キャッシュしてもいいけど、次に使うときは毎回サーバーに問い合わせてね」って設定。

「すぐに」ブラウザの戻るボタンを押すと、、、

この状態でブラウザの戻るボタンを押すと、、、

bfcache Network(HTTPリクエスト) サーバー(ログファイル)
有効 ✅ なし なし

ちゃんとbfcacheが有効になってるね!!

Devtoolでbfcacheについて確認してみると、bfcacheが使用されたのが確認できます。

要するに、ブラウザがページのスナップショットを復元しただけで、サーバー通信は起きていないってことです。

ちょ待てよ。。。

bfcacheって「短時間だけ」有効、ってChatGPTくんが言ってたな。

戻るボタンを押すまでに少し時間をあけたらどうなるんだ?

試してみます。

「時間をあけて」戻るボタンを押すと、、、

bfcache Network(HTTPリクエスト) サーバー(ログファイル)
無効 ❌ 有効 ✅ なし

なんとbfcacheが無効に、、、

Devtoolでbfcacheを確認してみると、、、

ここでいう、 The cache ってのはbfcacheのことだと思われます。

正確な時間は分かりませんが、1分経つとbfcacheは意図的に削除されました。

HTTPのレスポンスはどうなったかというと。。。

こんな感じでcache-controlの方でcacheされた内容を使ってページは表示されてました。

つまり、「bfcacheが消えたあとでも、別のキャッシュ層が効いてる」という状態。

cache-control: no-storeに指定

次に、cache-control: no-storeを設定して動作確認。

ちなみに Rails では以下のように設定できる。

response.headers['Cache-Control'] = 'no-store'

この状態で戻るボタンを押してみる、、、

bfcache Network(HTTPリクエスト) サーバー(ログファイル)
無効 ❌ 無効 ❌ 通信あり ✅

Devtoolでbfcacheを確認してみると、、、

bfcacheは使用されませんでした

理由は

Pages with cache-control:no-store header cannot enter back/forward cache.

だそうです。

cache-control:no-storeがheaderについたページはbfcacheに保存されないってこと。

HTTPリクエストについて確認してみると、

ちゃんとリクエストが飛んでいました!(ログファイルにも形跡あり)

まとめ

今回の検証でわかったのは、ブラウザが想像以上に“かしこい”(おせっかい)ってこと。

  • Cache-Control はあくまでHTTPレスポンスのキャッシュをコントロールする仕組み
  • 一方で bfcache は、ページ全体をメモリに凍結して高速で復元する仕組み
  • cache-control: no-store をつけると基本的に bfcache には入らない(けど、例外もある)
  • つまり「戻る=通信が走らない」ことが普通にある

最初は「なんで戻ると通信しないの?」というシンプルな疑問だったけど、

調べていくうちに「キャッシュにもいろんな層がある」ことがわかってきた。

今回の検証で、“戻るボタンの裏側”をちょっとだけ覗けた気がします。

ブラウザのキャッシュ、「完全に」理解したい。

補足

no-storeを指定したページでもbfcacheが有効になる。。。?

調べていく中で、「no-store を指定してても bfcache に入るケースがある」という、ちょっと意外な挙動も見つけました。

Chromeのチームが最近のアップデートで、Cache-Control: no-store が付いているページでも 一部の条件下では bfcache を有効化するようになった らしいです。

つまり、「キャッシュすんな!」って言ってるのに、ブラウザが“それはbfcacheだから別枠で扱うね”と判断するパターン。

実際、以下のような記事でも言及されています:

Simply put, Chrome is now enabling back/forward cache (bfcache) for pages that use Cache-Control: no-store in certain situations. Why does this matter? Because until now, using this header automatically made your pages ineligible for the back/forward cache.

https://www.rumvision.com/blog/chrome-now-ignores-cache-control-no-store-why-you-should-care
https://web.dev/articles/bfcache?hl=ja#minimize-no-store

自分の手元では上記の動作を確認できたが、no-storeがあってもページを bfcache に保存し、戻るで即座に復元することがある。つまり、「no-storeを付ければ戻る時に必ず通信が走る」とは限らない点に注意したい。。。。

bfcacheの確認方法

今回の記事でbfcacheが有効かどうかを確認していたが、以下のドキュメントがわかりやすい。

https://developer.chrome.com/docs/devtools/application/back-forward-cache?hl=ja

Discussion