bfcacheのSEO

back/forward cache(bfcache)とは、ページ全体をメモリで凍結し、戻る/進むのナビゲーションを瞬時にするブラウザー機能です。HTTPキャッシュとの違い、適格性を阻むもの、テスト方法、Core Web VitalsとSEOとの現実の間接的な関係を説明します。

初回公開:2026年7月3日 · 最終更新:2026年8月8日 · Advanced
言語

back/forward cache(bfcache)は、移動したページ全体(DOM、JavaScriptヒープ、実行状態)をブラウザーがメモリで凍結し、戻る/進むで再読み込みなしに復元する機能です。Googleの順位要因ではありませんが、復元されたナビゲーションはほぼ瞬時にLCPを測定し、再レイアウトがなければ追加CLSをほぼゼロにします。最大のブロッカーはunloadイベントで、pagehide、pageshow、event.persisted、notRestoredReasonsを使ってテストと診断を行います。Cache-Control: no-store、HTTPキャッシュ、Cache Storage、古い検索の「キャッシュされたページ」と混同せず、ブラウザーごとのルールと復元率を確認してください。

TL;DR — bfcacheはページ全体のメモリ内スナップショット(DOM+JSヒープ+実行状態)であり、再取得できるHTTPレスポンス、ブラウザーのメモリ内リソースキャッシュ、サービスワーカーのCache Storageではありません。ここが最初に押さえるべき概念上の区別です。離れるとJavaScriptを一時停止してページを凍結し、戻る/進むでは、凍結スナップショットがまだあれば、ネットワークリクエストなしで即座に解除・再表示します。ただし追い出しはいつでも起こり得るため、復元は「ありそう」でも保証ではありません。Google Searchの順位要因として文書化されておらず、Search CentralのCore Web Vitals文書にもありません。関係するのは、復元されたナビゲーションにおけるフィールドCWV(主にLCPとCLS)の測定という、間接的で範囲の限定されたものです。復元率、集計CWV評価、順位、コンバージョンは保証しません。最大の適格性ブロッカーはunloadハンドラー(Chromeでヒット率約18ポイント低下)です。歴史的に最大だったのはCache-Control: no-store(履歴ナビゲーションのモバイル約17%、デスクトップ約7%をブロック)ですが、Chromeは2025年の展開後、多くのno-storeページを条件付きで許可します。認証/Cookieの変更で追い出され、同じオープン接続APIでは引き続きブロックされます。オープン接続、タイマー、オブザーバーはpagehidefreezeで閉じるか一時停止し、pageshowresumeで再確立します。window.opener、Permissions Policy、フレームもブロック要因になり得るため、推測せずDevToolsまたはnotRestoredReasonsでフレームごとの理由を確認します。Chrome DevToolsで一回のテストを行い、フィールドではChrome限定のnotRestoredReasons APIで診断します(nullは復元の証拠ではなく、理由文も安定した契約ではありません)。ブラウザーごとに適格性ルールがあり、SPAのソフトナビゲーションは同じ扱いになりません。

Evidence for this claim The back-forward cache stores a complete page snapshot for instant history navigation. Scope: Current official or standards documentation. Confidence: high · Verified: web.dev: Back/forward cache Evidence for this claim Browser eligibility rules and APIs such as unload handlers can prevent bfcache use. Scope: Current official or standards documentation. Confidence: high · Verified: web.dev: bfcache eligibility

bfcacheの実態(正確さの背骨)

最も重要なのは、bfcacheがキャッシュされたHTTPレスポンスではなく、ページ全体のメモリ内スナップショットであることです。ページから離れると、ブラウザーは破棄する代わりにJavaScript実行を一時停止し、DOM、JSヒープ、進行中のタイマーなどページ全体を凍結してメモリに保持します。凍結スナップショットがまだ使える間に戻る/進むを押すと、ネットワークリクエストも再レンダリングもゼロで、離れたときのページを解除して再表示します。これは可能な復元であり保証ではありません。メモリ圧力、タイムアウト、イベント、ブラウザー固有のルールでスナップショットが追い出されれば、普通の履歴ナビゲーションになります。Googleの標準的な表現は、bfcacheが*“a browser optimization that enables instant back and forward navigation.”* (翻訳)(瞬時の戻る/進むナビゲーションを可能にするブラウザー最適化)だというものです。

これをHTTP/ブラウザーキャッシュと混同するのが、競合コンテンツに繰り返し現れる誤りです。HTTPキャッシュは過去のリクエストへのレスポンス、つまり再配信できるファイルを保存します。bfcacheは実行中のページを保存します。ChromeのDevTools文書はこの線引きを明示し、bfcacheは*“differs from browser cache and HTTP cache.”* (翻訳)(ブラウザーキャッシュやHTTPキャッシュとは異なる)としています。HTTPキャッシュのようにキャッシュヘッダーでbfcacheを「有効化」するわけではありません。ヘッダーが関係するのは、Cache-Control: no-storeが以前ページを不適格にしていた点だけです。

同じ区別は、bfcacheと混同される別の2つのキャッシュにも当てはまります。現在のセッションのためにコンパイル済みスクリプトやデコード済み画像を保持するブラウザーのメモリ内リソースキャッシュと、サイトがcaches.open()で自ら管理する明示的なリクエスト/レスポンス組であるサービスワーカーのCache Storageです。どちらもbfcacheと同時に動作できますが、bfcacheそのものではありません。bfcacheはキャッシュ資産や傍受レスポンスではなく、凍結されたページインスタンスです。

もう1つ明確にしておく価値があります。bfcacheは、Google(およびBing)が以前検索結果で公開していた古い「キャッシュされたページ」機能とは無関係です。それは検索インデックスに保存されたページスナップショットで、廃止されています。bfcacheはクライアント側のレンダリングエンジン機能です。

戻る/進むナビゲーションは実際どのくらい一般的か

これはニッチなエッジケースではありません。web.devによれば、“1 in 10 navigations on desktop and 1 in 5 on mobile are either back or forward.”(デスクトップの10回に1回、モバイルの5回に1回のナビゲーションは戻るまたは進む)です。ECサイトの商品カテゴリから商品へ移動して戻る流れ、検索結果、ページ分割されたコンテンツ、記事から記事への読書など、繰り返し/戻る/進むの流れがあるサイトでは、現実のナビゲーションの大きな部分をほぼ瞬時にできます。

ブラウザー対応

“All major browsers include a bfcache, including Chrome since version 96, Firefox and Safari.”(主要ブラウザーはすべてbfcacheを含み、Chromeはバージョン96以降、FirefoxとSafariも含まれます。)FirefoxとSafariにはそれぞれ長く運用されているbfcache実装があり、Chromiumベースのブラウザー(Edge、Brave、Opera、Arc)はChromeのものを継承します。MicrosoftのEdgeポリシー文書も、ページから離れると現在の状態(ドキュメントツリー、スクリプトなど)がback-forward cacheに保存される可能性があり、戻ればキャッシュ前の状態で復元・表示される可能性があると説明しています。Edgeでは既定で有効で、唯一のオフスイッチはサイト所有者ではなくIT管理者が制御するエンタープライズポリシーです。

重要な注意点は、ブラウザーごとにbfcacheの適格性ルールがあることです。Chrome DevToolsの「Test back/forward cache」に合格しても、FirefoxやSafariで適格とは限りません。Chromeでの合格は必要条件であって十分条件ではないと扱います。

bfcacheの適格性を阻むもの

unloadイベント — 最大の単一ブロッカー

この記事から1つだけ持ち帰るなら、unloadイベントの使用を止めることです。web.devはGoogle文書としては珍しい強さで、“Never use the unload event. Ever!”(unloadイベントは絶対に使うな)としています。Chromeでは、unloadハンドラーによりbfcacheヒット率が約18パーセントポイント低下します。自ら招く不適格要因として最大です。

Chromeが積極的に廃止している理由は2つあります。第一に最大のbfcacheブロッカーだからです。第二に、そもそもunloadは非常に信頼できません。モバイルでは、タブがバックグラウンド化されて終了し、ブラウザーがunload発火よりbfcacheを優先するため、頻繁に発火しません。「クリーンアップ」を任せたイベントが実行されないことが多く、同時に本物のパフォーマンス改善もブロックしています。

修正方法:

  • unloadpagehideに置き換える。 pagehideイベントはunloadが発火するすべての場合に加え、ページがbfcacheへ入る場合にも発火するため、厳密な上位互換です。確実な「ユーザーが離れる」クリーンアップにはvisibilitychangeを使います。
  • pageshowでbfcache復元を検出する。 pageshowを監視してevent.persistedを確認します。trueならページはbfcacheから復元されており、古いデータを更新したりページビューを再カウントしたりする合図です。
  • Permissions-Policyでunloadリスナーを先回りしてブロックする。 Permissions-Policy: unload=()レスポンスヘッダーで、unloadハンドラーが登録されること自体を防ぎます。Chromeは既定ポリシーをdenyへ段階的に移行しており、unload用のPermissions-PolicyはChrome 115から提供されています。

Cache-Control: no-store — 歴史的には最大、現在は複雑

ここは競合コンテンツの多くが誤る鮮度の論点です。歴史的には、Cache-Control: no-storeがbfcacheからページを除外する最大の単一理由でした。Chrome自身の数字では、モバイルの履歴ナビゲーションの約17%、デスクトップの約**7%**です。古いページを配信しないよう、多くのサイトが防御的にno-storeを設定します。しかしGoogleの主張は、bfcache復元は古いキャッシュレスポンスを読み込むのではなく、タブを開いたままにしたかのようにまったく同じライブページを再表示するため、この理由は弱くなるというものです。

Chromeは挙動を変更しましたが、普遍的ではなく条件付きです。実験はChrome 116で始まり、2025年3月と4月にユーザー100%への最終展開が行われました。Chromeは現在、安全条件を満たす多くのno-storeページをbfcacheに許可します。Chrome自身の文書によれば、凍結中に認証状態やCookieが変わるとページはbfcacheから追い出されます(サインアウトまたはCookieを消去した訪問者が、古いサインイン済みスナップショットを見ないためです)。また、IndexedDB、WebSocket、WebRTCなど、後述する同じオープン接続APIの固定リストは、他のページと同様にno-storeページを引き続き除外します。これは特定バージョン範囲のChrome固有の挙動であり、他のブラウザーや古いChromeも従うと想定できません。固定ルールを信じず、実際にテストするブラウザーとバージョンのDevTools/notRestoredReasonsレポートを取得します。実務上の結論:no-storeを無条件かつ永続的なbfcacheブロッカーと列挙するガイド(この古い版を含む)は古く、完全に解決済みと扱うのも古い見方です。ページの鮮度が本当に重要なら、Chromeの文書はno-storeではなくno-cacheまたは短いmax-age(例:max-age=60)を示唆しています。

オープン接続、オブザーバー、その他のブロッカー

ナビゲーションの時点で、特定のオープンリソースが適格性をブロックすることがあります。どれがブロックし、完全にブロックするのか、閉じて再接続できるだけなのかは、ブラウザーとバージョンによって異なります。以下は固定された永続的なブロッカー一覧ではなく、パターンの例として扱います。

  • 進行中のfetch()XMLHttpRequestリクエスト。
  • オープンなIndexedDBトランザクション。
  • オープンなWebSocketWebRTC接続、タイマー、オブザーバーMutationObserverIntersectionObserverなど)。ここは改善が続く領域です。Microsoft Edgeの最近のリリースノートでは、オープンWebSocketがbfcacheを完全にブロックする代わりに、ページがbfcacheへ入ると閉じられるようになり、pageshowイベントのevent.persisted確認で再接続するよう推奨されています。単にページを除外するのではなく、ブロッカーを減らすChromeの広い流れとも一致します。

固定リストを暗記するより、構築すべき一般パターンがあります。pagehidefreezeの処理でオープン接続、タイマー、オブザーバーを閉じるか一時停止し、event.persistedがtrueのとき、pageshowresumeの処理で再確立します。どのAPIが完全に適格性をブロックし、どれが一時停止されて再接続できるだけなのかをブラウザーが変更しても、このパターンは保てます。

window.opener、Permissions Policy、フレーム。 window.opener参照、特定のPermissions Policy、埋め込み(同一オリジンまたはクロスオリジン)フレームも適格性に影響します。このチェックリストはAhrefsのCLSガイドとChromeの文書から整理したものです。ただし、一般的なチェックリストから実際の原因を決めつけないでください。Chrome DevToolsパネルとnotRestoredReasons APIは、トップフレームと各iframeをフレームごとにブロック理由を報告します。実際にブロックしたフレームがトップレベルページとは限らないためです。一般的な一覧から推測せず、テスト中のブラウザーでフレーム単位のレポートから実際の理由を取得します。

ライフサイクルイベント/状態の順序を正しく扱う

各ライフサイクルイベントが実際に証明することと、単に示唆することを混同するのは、ここで適格性の誤りに次いで多い正確性のバグです。

イベント/状態シグナル実際の意味すること
pagehideevent.persisted === trueキャッシュする意図ブラウザーがページをbfcache用に凍結しようとしている。キャッシュ登録の確認ではないここで接続、タイマー、オブザーバーを閉じる/一時停止する。実際に復元されるとは想定しない
freeze一時停止JS実行は一時停止したが、復元前にページが追い出される可能性はあるpagehideで行ったこと以外は不要
(イベントなし)追い出しの可能性メモリ圧力、タイムアウト、ブラウザールールで、凍結ページはいつでもメモリから削除され得る。これを知らせるイベントは発火しない後でクリーンアップが走るとは頼らず、pagehidefreezeで無条件に行う
pageshowevent.persisted === true復元の確認bfcache復元が実際に起きた唯一の信頼できるシグナル時間依存/機密状態を更新し、閉じた接続を再接続し、分析ビューを1回だけ数える
resume再開確認済み復元後にJS実行が再開したfreezeで一時停止したものを再接続する

実務上のルールは、pagehide.persisted意図として扱い、証拠とはしないことです。復元を見る前にページが追い出されることがあります。実際に復元が起きた証拠はpageshow.persisted === trueだけです。クリーンアップは通常のナビゲーションでも安価で安全なのでpagehidefreezeで無条件に行い、復元専用の処理はevent.persistedで条件付けてpageshowresumeで行います。通常の新規読み込みでデータを更新したり分析ビューを二重計上したりしないためです。

bfcacheをテストして診断する方法

ラボ/一回限り:Chrome DevTools

DevTools → Application → Background services → Back/forward cacheを開き、**「Test back/forward cache」**をクリックします。Chromeは自動的にchrome://terms/へ移動して戻り、成功または具体的なブロッカー一覧を報告します。1 URLずつ確認するのに適しています。

フィールド/本番:notRestoredReasons API

以前、適格性を確認する唯一の方法は手動の1 URLずつのDevToolsテストで、実ユーザーのナビゲーションがなぜブロックされたかを見る方法はありませんでした。Chrome 123以降で提供されるPerformanceNavigationTimingnotRestoredReasonsプロパティがこの差を埋めます。実際のフィールドデータで、トップフレームと同一オリジンiframeの具体的なブロック理由を報告します。

const nav = performance.getEntriesByType('navigation')[0];
console.log(nav.notRestoredReasons);

Chrome自身のAPI指針から、使うときに正しく扱う点を挙げます。

  • Chrome限定(123以降)。 FirefoxとSafariには同等のフィールドAPIがないため、そこでの復元率を知るには手動のスポットチェックが必要です。
  • nullは曖昧で、合格のサインではない。 ページが復元された場合も、ブラウザーが理由を収集しなかった場合もあります。Chromeの文書も、nullを復元成功の証拠としないよう述べています。
  • 理由文は安定した契約ではない。 文字列一致をハードコードせず、正確な文言はChromeのバージョンで変わる可能性があるため、理由ごとにグループ化して傾向を追います。

notRestoredReasonspageshow.persistedの復元率とともに、修正の前後で取得します。単一のスナップショットではなく傾向を比較し、APIが届かないブラウザーについてはFirefoxとSafariで手動のDevTools/ラボチェックも行います。本番RUMでbfcacheを大規模に診断するときに使うツールですが、全体像そのものとは扱いません。

bfcacheとCore Web Vitals — 正確な関係

ここは競合コンテンツが曖昧にするニュアンスであり、正確に押さえる価値のある切り口です。

bfcache復元の測定方法。 ブラウザー(したがってCrUXフィールドデータ)は、bfcacheから復元されたナビゲーションを非常に速い「ページ読み込み」として数えます。ほぼ瞬時のLCPで、正しく実装されて再レイアウトが不要なら、再レンダリングがないため追加のCLSは実質ゼロです。DebugBearの実環境比較では、bfcache復元ページのLCPは約100ms、未キャッシュ読み込みは約427msでした。これがbfcacheが私のAhrefs CLSチェックリストでLCPとCLSのレバーとして登場する理由です。そこでは簡潔にこう書いています。“Make sure your pages are eligible for bfcache. The back/forward cache keeps pages in the browser cache. It allows for instant loading of a page that was already loaded, meaning no layout shifts will happen.” (翻訳)(ページがbfcacheに適格であることを確認してください。back/forward cacheはページをブラウザーキャッシュに保持し、すでに読み込んだページを瞬時に読み込めるため、レイアウトシフトは起こりません。)

正確にするべきスコープ上の注意点が2つあります。第一に影響するのは、CrUXが戻る/進む(navigation-typeディメンション)と分類するナビゲーションだけです。大半のサイトで多数を占める初回訪問や再読み込みについては何も言いません。第二に、復元されたユーザーの測定上の体験が改善しても保証ではありません。bfcacheから追い出されたユーザー(前述のライフサイクル表を参照)は改善されない通常の読み込みになります。bfcache適格性の作業が動かすのは、総トラフィックの固定シェアではなく、戻る/進むナビゲーションにおける復元率です。集計フィールドのCore Web Vitals評価、順位、コンバージョンも保証しません。一般的なパフォーマンス/SEO修正ではなく、現実に測定できる、範囲の明確なレバーです。

bfcacheは順位要因か? いいえ。 これは防御可能で差別化された主張です。Google自身のCore Web Vitals順位文書にはbfcacheがまったく登場しません。正直な影響連鎖は、bfcache適格性 → 戻る/進むナビゲーションのフィールドCWV(主にLCP/CLS)改善 → Core Web VitalsはGoogleが順位システムの報いるものと整合すると説明する「ページエクスペリエンス」シグナルの1入力、です。「bfcacheが順位を上げる」より、実質的に弱く、正確な主張です。bfcacheは正しくはレンダリングエンジンの機能であり、クローラーの機能ではありません。GooglebotやBingbotがページをクロールする方法とは関係ないため、robots.txtやサイトマップのような「SEOに対するBingのbfcache見解」はありません。

SPAとソフトナビゲーション。 bfcacheは実際のブラウザーナビゲーションと履歴イベントで動作します。SPAのクライアント側「ソフト」ルート変更(実際のブラウザーナビゲーションを起こさないJS駆動の表示切替)はbfcacheイベントではなく、同じ扱いになりません。RUMツールがCore Web Vitalsをソフトナビゲーションに帰属させようとすると、CrUXとRUMの測定が不一致になることがあります。JSフレームワークのサイトを監査するなら、指摘すべき点です。

実際のウェブでbfcacheブロッカーはどのくらい一般的か

HTTP ArchiveのWeb Almanacが追跡しています。固定した古いニュースではなく、変化中の領域です。2022年版では、unloadとno-storeの条件だけで、モバイルページの少なくとも約22%がbfcache不適格でした。その後、unloadハンドラーの使用はサイト層とデバイス全体で減少していますが、Cache-Control: no-storeの使用は増えました。2025年章では約23%のサイトで、2024年の約21%から増えており、認証/パーソナライズ体験の増加と厳格なコンプライアンス要件が一因とされています。

引用する価値がある直感に反する発見は、大規模でトラフィックの多いサイトほど、自分のbfcacheをブロックしやすいことです。上位1 000サイトでは、デスクトップページの約28%、モバイルページの20%が今もunloadハンドラーを使います。全サイトではデスクトップ約11%、モバイル約10%にすぎません。大規模サイトはレガシー分析やunload依存コードを多く抱えることが理由です。失う戻る/進むトラフィックが最も多いサイトが、自分で妨げていることがよくあります。

どこに位置付けるか

bfcacheは、このクラスターにある複数のパフォーマンスレバーの1つです。効果はCore Web Vitalsのフィールドデータ、特にCumulative Layout ShiftLargest Contentful Paintに現れます。復元ページは再レイアウトなしで即座に再表示されるためです。ライブなページのスナップショットではなくファイルを保存するcachingとは別物ですが、両者はCache-Controlヘッダーで接点を持ちます。Interaction to Next Paintとの直接の関係はないため、無理に結び付けません。

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.