[{"data":1,"prerenderedAt":1657},["ShallowReactive",2],{"content:\u002Fadvanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache":3,"surroundings:\u002Fadvanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache":1650},{"id":4,"title":5,"body":6,"description":1631,"extension":1632,"meta":1633,"navigation":1643,"path":1644,"seo":1645,"stem":1648,"__hash__":1649},"content\u002Fadvanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache\u002Findex.md","Back\u002FForward Cache (bfcache)",{"type":7,"value":8,"toc":1612},"minimark",[9,14,24,27,39,152,157,160,183,190,252,256,316,320,323,327,330,505,508,512,515,644,648,703,710,714,717,783,915,918,922,928,937,946,959,973,977,986,1121,1128,1132,1144,1153,1159,1176,1199,1203,1212,1231,1242,1257,1261,1291,1352,1356,1359,1415,1418,1422,1432,1436,1454,1466,1475,1484,1493,1502,1517,1529,1533,1563,1567,1597,1602,1605,1608],[10,11,13],"h1",{"id":12},"backforward-cache-bfcache-making-back-navigations-instant","Back\u002FForward Cache (bfcache): Making Back Navigations Instant",[15,16,17,18,23],"p",{},"This topic belongs to ",[19,20,22],"a",{"href":21},"\u002Fadvanced-caching-strategies-cdn-architecture\u002F","Advanced Caching Strategies & CDN Architecture",", and covers the one cache that makes navigations not merely fast but instant. When a user presses Back or Forward, a browser with an eligible page in its back\u002Fforward cache does not reload anything: it restores the complete page — DOM, JavaScript heap, scroll position — from memory, typically in well under 100ms. No network, no parsing, no rendering from scratch.",[15,25,26],{},"Back and forward navigations are a large share of all navigations — on mobile, roughly one in ten, and much more on browse-heavy sites such as search results, product listings and news feeds where users return to a list after viewing an item. Every one of those that is served from bfcache is effectively a perfect Core Web Vitals experience: LCP close to zero, no layout shift from loading, and an interactive page immediately. Every one that is not — because the page is ineligible — is a full reload, often slower than the first visit because caches have been evicted.",[15,28,29,30,34,35,38],{},"The browser decides eligibility per page, and a surprising number of common patterns make pages ineligible: ",[31,32,33],"code",{},"unload"," handlers, ",[31,36,37],{},"Cache-Control: no-store"," on the document, open connections, unclosed IndexedDB transactions, and some third-party scripts. Most are fixable without product changes.",[15,40,41],{},[42,43,49,50,49,57,49,61,49,64,49,73,49,79,49,88,49,94,49,99,49,104,49,107,49,110,49,113,49,116,49,119,49,122,49,127,49,131,49,133,49,137,49,139,49,142,49,144,49,147,49,149,49],"svg",{"viewBox":44,"width":45,"role":46,"ariaLabel":47,"style":48},"0 0 760 228","100%","img","Comparison of what happens on a back navigation when the page is restored from bfcache versus reloaded.","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)"," ",[51,52],"rect",{"className":53,"x":55,"y":55,"width":45,"height":45,"fill":56},[54],"svg-canvas","0","#ffffff",[58,59,60],"title",{},"Back navigation with and without bfcache",[62,63,47],"desc",{},[51,65],{"x":66,"y":66,"width":67,"height":68,"rx":69,"fill":70,"stroke":71,"style":72},"1","758","226","10","none","currentColor","stroke-opacity:0.18",[74,75,60],"text",{"x":76,"y":77,"fill":71,"style":78},"28.0","34.0","font-size:16px;font-weight:700",[51,80],{"x":76,"y":81,"width":82,"height":83,"rx":84,"fill":85,"stroke":86,"style":87},"56.0","340.0","150.0","6","#ffc300","#b8860b","fill-opacity:0.24;stroke-opacity:0.9",[74,89,93],{"x":90,"y":91,"fill":71,"style":92},"42.0","82.0","font-size:14px;font-weight:700","Restored from bfcache",[74,95,98],{"x":90,"y":96,"fill":71,"style":97},"108.0","font-size:12.5px;font-weight:700","•",[74,100,103],{"x":81,"y":96,"fill":71,"style":101,"textAnchor":102},"font-size:12.5px","start","Page restored from memory",[74,105,98],{"x":90,"y":106,"fill":71,"style":97},"132.0",[74,108,109],{"x":81,"y":106,"fill":71,"style":101,"textAnchor":102},"No requests, no parsing, no rendering",[74,111,98],{"x":90,"y":112,"fill":71,"style":97},"156.0",[74,114,115],{"x":81,"y":112,"fill":71,"style":101,"textAnchor":102},"Scroll and form state intact",[74,117,98],{"x":90,"y":118,"fill":71,"style":97},"180.0",[74,120,121],{"x":81,"y":118,"fill":71,"style":101,"textAnchor":102},"Visible in well under 100ms",[51,123],{"x":124,"y":81,"width":82,"height":83,"rx":84,"fill":125,"stroke":125,"style":126},"392.0","#0466c8","fill-opacity:0.14;stroke-opacity:0.9",[74,128,130],{"x":129,"y":91,"fill":71,"style":92},"406.0","Ineligible: full reload",[74,132,98],{"x":129,"y":96,"fill":71,"style":97},[74,134,136],{"x":135,"y":96,"fill":71,"style":101,"textAnchor":102},"420.0","HTML requested again (often revalidated)",[74,138,98],{"x":129,"y":106,"fill":71,"style":97},[74,140,141],{"x":135,"y":106,"fill":71,"style":101,"textAnchor":102},"CSS, JS parsed and executed again",[74,143,98],{"x":129,"y":112,"fill":71,"style":97},[74,145,146],{"x":135,"y":112,"fill":71,"style":101,"textAnchor":102},"Hydration, data fetches repeated",[74,148,98],{"x":129,"y":118,"fill":71,"style":97},[74,150,151],{"x":135,"y":118,"fill":71,"style":101,"textAnchor":102},"Often 1-3s on mobile",[153,154,156],"h2",{"id":155},"the-experience-degradation-this-topic-addresses","The Experience Degradation This Topic Addresses",[15,158,159],{},"The symptom rarely shows up in a dashboard by name. Users experience slow back navigations, lost scroll position on long lists, and filters reset after returning from a product page. In metrics, bfcache misses show up as:",[161,162,163,171,177],"ul",{},[164,165,166,170],"li",{},[167,168,169],"strong",{},"Lower overall LCP quality"," — back navigations that reload count as page views with full LCP; restorations report near-instant metrics in RUM.",[164,172,173,176],{},[167,174,175],{},"Worse engagement on browse flows"," — the list-detail-list pattern feels sluggish, increasing abandonment.",[164,178,179,182],{},[167,180,181],{},"Extra server load"," — every ineligible back navigation is a request, often uncached for personalised pages.",[15,184,185,186,189],{},"Chrome reports bfcache eligibility explicitly in DevTools and through the ",[31,187,188],{},"notRestoredReasons"," API, which makes this one of the most diagnosable performance problems on the web.",[15,191,192],{},[42,193,49,196,49,199,49,202,49,204,49,207,49,209,49,216,49,223,49,228,49,232,49,237,49,241,49,244,49,248,49],{"viewBox":194,"width":45,"role":46,"ariaLabel":195,"style":48},"0 0 760 163","Bar chart of back-navigation time for a product listing page restored from bfcache versus reloaded with warm and cold HTTP caches.",[51,197],{"className":198,"x":55,"y":55,"width":45,"height":45,"fill":56},[54],[58,200,201],{},"Time to visible page on back navigation (mid-tier phone)",[62,203,195],{},[51,205],{"x":66,"y":66,"width":67,"height":206,"rx":69,"fill":70,"stroke":71,"style":72},"161",[74,208,201],{"x":76,"y":77,"fill":71,"style":78},[74,210,215],{"x":211,"y":212,"fill":71,"style":213,"textAnchor":214},"183.8","70.0","font-size:13px","end","bfcache restore",[51,217],{"x":218,"y":81,"width":219,"height":220,"rx":221,"fill":125,"stroke":125,"style":222},"195.8","10.5","19","3","fill-opacity:0.55;stroke-opacity:0.9",[74,224,227],{"x":225,"y":212,"fill":71,"style":226},"212.3","font-size:12px;font-weight:600","60ms",[74,229,231],{"x":211,"y":230,"fill":71,"style":213,"textAnchor":214},"101.0","Reload, warm HTTP cache",[51,233],{"x":218,"y":234,"width":235,"height":220,"rx":221,"fill":85,"stroke":86,"style":236},"87.0","201.1","fill-opacity:0.7;stroke-opacity:0.9",[74,238,240],{"x":239,"y":230,"fill":71,"style":226},"402.9","1150ms",[74,242,243],{"x":211,"y":106,"fill":71,"style":213,"textAnchor":214},"Reload, cold cache",[51,245],{"x":218,"y":246,"width":247,"height":220,"rx":221,"fill":85,"stroke":86,"style":236},"118.0","472.2",[74,249,251],{"x":250,"y":106,"fill":71,"style":226},"674.0","2700ms",[153,253,255],{"id":254},"prerequisites","Prerequisites",[161,257,258,264,277,303],{},[164,259,260,263],{},[167,261,262],{},"Chrome DevTools"," → Application → Back\u002Fforward cache, which tests a page and lists blocking reasons.",[164,265,266,272,273,276],{},[167,267,268,269,271],{},"The ",[31,270,188],{}," API"," (Chromium) via ",[31,274,275],{},"PerformanceNavigationTiming.notRestoredReasons",", for field data.",[164,278,279,282,283,286,287,290,291,294,295,298,299,302],{},[167,280,281],{},"RUM that records navigation type",", distinguishing ",[31,284,285],{},"back_forward"," reloads from restorations (the ",[31,288,289],{},"pageshow"," event's ",[31,292,293],{},"persisted"," flag, or ",[31,296,297],{},"navigationType: 'back-forward-cache'"," in the ",[31,300,301],{},"web-vitals"," library).",[164,304,305,315],{},[167,306,307,308,310,311,314],{},"An inventory of ",[31,309,33],{},"\u002F",[31,312,313],{},"beforeunload"," handlers"," and third-party scripts — both are frequent blockers.",[153,317,319],{"id":318},"_1-environment-setup-test-eligibility-in-devtools","1. Environment Setup: Test Eligibility in DevTools",[15,321,322],{},"Open the page, go to Application → Back\u002Fforward cache, and click \"Test back\u002Fforward cache\". DevTools navigates away and back, then reports whether the page was restored and, if not, why — distinguishing issues you can fix (\"actionable\"), ones that need support from a third party, and ones caused by browser limitations.",[153,324,326],{"id":325},"_2-capture-a-baseline-in-the-field","2. Capture a Baseline in the Field",[15,328,329],{},"Measure what share of back\u002Fforward navigations are restored, and why the others are not.",[331,332,337],"pre",{"className":333,"code":334,"language":335,"meta":336,"style":336},"language-javascript shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","addEventListener('pageshow', (event) => {\n  const nav = performance.getEntriesByType('navigation')[0];\n  if (event.persisted) {\n    report({ bfcache: 'restored' });\n  } else if (nav?.type === 'back_forward') {\n    report({ bfcache: 'missed', reasons: nav.notRestoredReasons ?? null });\n  }\n});\n\u002F\u002F trade-off: notRestoredReasons is Chromium-only and reports reasons for the\n\u002F\u002F main frame and same-origin frames in detail; cross-origin iframes are\n\u002F\u002F summarised. Use it to rank causes, not as a complete list everywhere.\n","javascript","",[31,338,339,373,405,414,429,453,474,480,486,493,499],{"__ignoreMap":336},[340,341,344,348,352,356,359,363,366,370],"span",{"class":342,"line":343},"line",1,[340,345,347],{"class":346},"smZ65","addEventListener",[340,349,351],{"class":350},"saISM","(",[340,353,355],{"class":354},"sZ8jY","'pageshow'",[340,357,358],{"class":350},", (",[340,360,362],{"class":361},"sQw3B","event",[340,364,365],{"class":350},") ",[340,367,369],{"class":368},"sPARh","=>",[340,371,372],{"class":350}," {\n",[340,374,376,379,383,386,389,392,394,397,400,402],{"class":342,"line":375},2,[340,377,378],{"class":368},"  const",[340,380,382],{"class":381},"sPXB4"," nav",[340,384,385],{"class":368}," =",[340,387,388],{"class":350}," performance.",[340,390,391],{"class":346},"getEntriesByType",[340,393,351],{"class":350},[340,395,396],{"class":354},"'navigation'",[340,398,399],{"class":350},")[",[340,401,55],{"class":381},[340,403,404],{"class":350},"];\n",[340,406,408,411],{"class":342,"line":407},3,[340,409,410],{"class":368},"  if",[340,412,413],{"class":350}," (event.persisted) {\n",[340,415,417,420,423,426],{"class":342,"line":416},4,[340,418,419],{"class":346},"    report",[340,421,422],{"class":350},"({ bfcache: ",[340,424,425],{"class":354},"'restored'",[340,427,428],{"class":350}," });\n",[340,430,432,435,438,441,444,447,450],{"class":342,"line":431},5,[340,433,434],{"class":350},"  } ",[340,436,437],{"class":368},"else",[340,439,440],{"class":368}," if",[340,442,443],{"class":350}," (nav?.type ",[340,445,446],{"class":368},"===",[340,448,449],{"class":354}," 'back_forward'",[340,451,452],{"class":350},") {\n",[340,454,456,458,460,463,466,469,472],{"class":342,"line":455},6,[340,457,419],{"class":346},[340,459,422],{"class":350},[340,461,462],{"class":354},"'missed'",[340,464,465],{"class":350},", reasons: nav.notRestoredReasons ",[340,467,468],{"class":368},"??",[340,470,471],{"class":381}," null",[340,473,428],{"class":350},[340,475,477],{"class":342,"line":476},7,[340,478,479],{"class":350},"  }\n",[340,481,483],{"class":342,"line":482},8,[340,484,485],{"class":350},"});\n",[340,487,489],{"class":342,"line":488},9,[340,490,492],{"class":491},"sjfSM","\u002F\u002F trade-off: notRestoredReasons is Chromium-only and reports reasons for the\n",[340,494,496],{"class":342,"line":495},10,[340,497,498],{"class":491},"\u002F\u002F main frame and same-origin frames in detail; cross-origin iframes are\n",[340,500,502],{"class":342,"line":501},11,[340,503,504],{"class":491},"\u002F\u002F summarised. Use it to rank causes, not as a complete list everywhere.\n",[15,506,507],{},"The restoration rate — restored ÷ (restored + missed back\u002Fforward navigations) — is the topic's headline number. Sites that have never looked at it commonly find it under 30%; well-tuned sites reach 80–90% in Chromium.",[153,509,511],{"id":510},"_3-isolate-the-blocking-reasons","3. Isolate the Blocking Reasons",[15,513,514],{},"Group field reasons by frequency. The common ones, roughly in order of how often they appear:",[15,516,517],{},[42,518,49,521,49,524,49,527,49,529,49,532,49,534,49,539,49,544,49,548,49,553,49,556,49,560,49,564,49,568,49,570,49,574,49,576,49,579,49,582,49,585,49,587,49,590,49,592,49,595,49,598,49,602,49,604,49,606,49,608,49,611,49,614,49,618,49,620,49,622,49,624,49,627,49,630,49,634,49,636,49,639,49,641,49],{"viewBox":519,"width":45,"role":46,"ariaLabel":520,"style":48},"0 0 760 258","The most common reasons pages are not restored from bfcache, whether they are under the site's control, and the fix for each.",[51,522],{"className":523,"x":55,"y":55,"width":45,"height":45,"fill":56},[54],[58,525,526],{},"Common bfcache blockers and fixes",[62,528,520],{},[51,530],{"x":66,"y":66,"width":67,"height":531,"rx":69,"fill":70,"stroke":71,"style":72},"256",[74,533,526],{"x":76,"y":77,"fill":71,"style":78},[51,535],{"x":76,"y":81,"width":536,"height":537,"rx":55,"fill":71,"stroke":71,"style":538},"210.0","30.0","fill-opacity:0.06;stroke-opacity:0.4",[74,540,543],{"x":541,"y":542,"fill":71,"style":97,"textAnchor":102},"38.0","75.5","Reason",[51,545],{"x":546,"y":81,"width":547,"height":537,"rx":55,"fill":71,"stroke":71,"style":538},"238.0","247.0",[74,549,552],{"x":550,"y":542,"fill":71,"style":97,"textAnchor":551},"361.5","middle","Fixable by you?",[51,554],{"x":555,"y":81,"width":547,"height":537,"rx":55,"fill":71,"stroke":71,"style":538},"485.0",[74,557,559],{"x":558,"y":542,"fill":71,"style":97,"textAnchor":551},"608.5","Fix",[51,561],{"x":76,"y":562,"width":536,"height":537,"rx":55,"fill":70,"stroke":71,"style":563},"86.0","stroke-opacity:0.35",[74,565,567],{"x":541,"y":566,"fill":71,"style":97,"textAnchor":102},"105.5","unload handler",[51,569],{"x":546,"y":562,"width":547,"height":537,"rx":55,"fill":125,"stroke":125,"style":126},[74,571,573],{"x":550,"y":566,"fill":71,"style":572,"textAnchor":551},"font-size:12px","yes",[51,575],{"x":555,"y":562,"width":547,"height":537,"rx":55,"fill":70,"stroke":71,"style":563},[74,577,578],{"x":558,"y":566,"fill":71,"style":572,"textAnchor":551},"Use pagehide or visibilitychange",[51,580],{"x":76,"y":581,"width":536,"height":537,"rx":55,"fill":70,"stroke":71,"style":563},"116.0",[74,583,37],{"x":541,"y":584,"fill":71,"style":97,"textAnchor":102},"135.5",[51,586],{"x":546,"y":581,"width":547,"height":537,"rx":55,"fill":125,"stroke":125,"style":126},[74,588,589],{"x":550,"y":584,"fill":71,"style":572,"textAnchor":551},"yes, with care",[51,591],{"x":555,"y":581,"width":547,"height":537,"rx":55,"fill":70,"stroke":71,"style":563},[74,593,594],{"x":558,"y":584,"fill":71,"style":572,"textAnchor":551},"Use no-cache + private where possible",[51,596],{"x":76,"y":597,"width":536,"height":537,"rx":55,"fill":70,"stroke":71,"style":563},"146.0",[74,599,601],{"x":541,"y":600,"fill":71,"style":97,"textAnchor":102},"165.5","Open WebSocket \u002F WebRTC",[51,603],{"x":546,"y":597,"width":547,"height":537,"rx":55,"fill":125,"stroke":125,"style":126},[74,605,573],{"x":550,"y":600,"fill":71,"style":572,"textAnchor":551},[51,607],{"x":555,"y":597,"width":547,"height":537,"rx":55,"fill":70,"stroke":71,"style":563},[74,609,610],{"x":558,"y":600,"fill":71,"style":572,"textAnchor":551},"Close on pagehide; reopen on pageshow",[51,612],{"x":76,"y":613,"width":536,"height":537,"rx":55,"fill":70,"stroke":71,"style":563},"176.0",[74,615,617],{"x":541,"y":616,"fill":71,"style":97,"textAnchor":102},"195.5","Unfinished IndexedDB transaction",[51,619],{"x":546,"y":613,"width":547,"height":537,"rx":55,"fill":125,"stroke":125,"style":126},[74,621,573],{"x":550,"y":616,"fill":71,"style":572,"textAnchor":551},[51,623],{"x":555,"y":613,"width":547,"height":537,"rx":55,"fill":70,"stroke":71,"style":563},[74,625,626],{"x":558,"y":616,"fill":71,"style":572,"textAnchor":551},"Commit or close before pagehide",[51,628],{"x":76,"y":629,"width":536,"height":537,"rx":55,"fill":70,"stroke":71,"style":563},"206.0",[74,631,633],{"x":541,"y":632,"fill":71,"style":97,"textAnchor":102},"225.5","Third-party iframe or script",[51,635],{"x":546,"y":629,"width":547,"height":537,"rx":55,"fill":71,"stroke":71,"style":538},[74,637,638],{"x":550,"y":632,"fill":71,"style":572,"textAnchor":551},"via vendor",[51,640],{"x":555,"y":629,"width":547,"height":537,"rx":55,"fill":70,"stroke":71,"style":563},[74,642,643],{"x":558,"y":632,"fill":71,"style":572,"textAnchor":551},"Update, replace or delay the vendor",[153,645,647],{"id":646},"_4-apply-the-fixes","4. Apply the Fixes",[649,650,651,664,678,693],"ol",{},[164,652,653,658,659,663],{},[167,654,655,656,314],{},"Remove ",[31,657,33],{}," — your own and third parties' — as described in ",[19,660,662],{"href":661},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache\u002Freplacing-unload-handlers-for-bfcache\u002F","replacing unload handlers for bfcache",".",[164,665,666,673,674,663],{},[167,667,668,669,672],{},"Reconsider ",[31,670,671],{},"no-store"," on HTML"," — see ",[19,675,677],{"href":676},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache\u002Fcache-control-no-store-and-bfcache\u002F","Cache-Control no-store and bfcache",[164,679,680,686,687,689,690,692],{},[167,681,682,683],{},"Close connections on ",[31,684,685],{},"pagehide"," and reopen them on ",[31,688,289],{}," when ",[31,691,293],{}," is true.",[164,694,695,698,699,663],{},[167,696,697],{},"Restore freshness on return"," — update prices, stock or session state when a page is restored, covered in ",[19,700,702],{"href":701},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache\u002Frestoring-state-on-pageshow-after-bfcache\u002F","restoring state on pageshow after bfcache",[15,704,705,706,663],{},"The step-by-step resolution for each blocker is in ",[19,707,709],{"href":708},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache\u002Ffixing-bfcache-eligibility-blockers\u002F","fixing bfcache eligibility blockers",[153,711,713],{"id":712},"deconstructing-a-back-navigation","Deconstructing a Back Navigation",[15,715,716],{},"A back navigation can take one of three paths, each with very different cost:",[718,719,720,739],"table",{},[721,722,723],"thead",{},[724,725,726,730,733,736],"tr",{},[727,728,729],"th",{},"Path",[727,731,732],{},"What happens",[727,734,735],{},"Typical time (mobile)",[727,737,738],{},"Metrics reported",[740,741,742,756,770],"tbody",{},[724,743,744,747,750,753],{},[745,746,215],"td",{},[745,748,749],{},"page resumed from memory",[745,751,752],{},"\u003C 100ms",[745,754,755],{},"near-zero LCP; CLS\u002FINP continue from restoration",[724,757,758,761,764,767],{},[745,759,760],{},"HTTP-cache reload",[745,762,763],{},"HTML revalidated or served from cache; subresources mostly cached",[745,765,766],{},"0.8–1.5s",[745,768,769],{},"full LCP; full startup work",[724,771,772,775,778,781],{},[745,773,774],{},"Network reload",[745,776,777],{},"HTML and some subresources fetched",[745,779,780],{},"1.5–3s+",[745,782,769],{},[15,784,785],{},[42,786,49,789,49,792,49,795,49,797,49,814,49,817,49,819,49,823,49,829,49,832,49,836,49,844,49,849,49,853,49,859,49,862,49,866,49,868,49,871,49,874,49,877,49,880,49,883,49,886,49,890,49,892,49,895,49,898,49,901,49,905,49,908,49,911,49],{"viewBox":787,"width":45,"role":46,"ariaLabel":788,"style":48},"0 0 760 325","Decision sequence for how the browser serves a back navigation, from bfcache restore to network reload.",[51,790],{"className":791,"x":55,"y":55,"width":45,"height":45,"fill":56},[54],[58,793,794],{},"Which path will a back navigation take?",[62,796,788],{},[798,799,800],"defs",{},[801,802,809],"marker",{"id":803,"viewBox":804,"refX":805,"refY":806,"markerWidth":807,"markerHeight":807,"orient":808},"fabbb40f4f","0 0 10 10","9","5","7","auto-start-reverse",[810,811],"path",{"d":812,"fill":71,"style":813},"M0 0 L10 5 L0 10 z","fill-opacity:0.7",[51,815],{"x":66,"y":66,"width":67,"height":816,"rx":69,"fill":70,"stroke":71,"style":72},"323",[74,818,794],{"x":76,"y":77,"fill":71,"style":78},[51,820],{"x":76,"y":81,"width":821,"height":822,"rx":84,"fill":71,"stroke":71,"style":538},"320.0","35.0",[74,824,828],{"x":825,"y":826,"fill":71,"style":827,"textAnchor":551},"188.0","78.0","font-size:13px;font-weight:700","Page eligible and still in bfcache?",[51,830],{"x":831,"y":81,"width":821,"height":822,"rx":84,"fill":125,"stroke":125,"style":126},"412.0",[74,833,835],{"x":834,"y":826,"fill":71,"style":101,"textAnchor":551},"572.0","Restore from memory — instant",[342,837],{"x1":838,"y1":839,"x2":840,"y2":839,"stroke":71,"strokeWidth":841,"style":842,"markerEnd":843},"348.0","73.5","410.0","1.5","stroke-opacity:0.6","url(#fabbb40f4f)",[74,845,573],{"x":846,"y":847,"fill":125,"style":848,"textAnchor":551},"380.0","66.5","font-size:11.5px;font-weight:700",[342,850],{"x1":825,"y1":851,"x2":825,"y2":852,"stroke":71,"strokeWidth":841,"style":842,"markerEnd":843},"91.0","125.0",[74,854,858],{"x":855,"y":856,"fill":857,"style":848},"196.0","113.0","#51617a","no",[51,860],{"x":76,"y":861,"width":821,"height":822,"rx":84,"fill":71,"stroke":71,"style":538},"127.0",[74,863,865],{"x":825,"y":864,"fill":71,"style":827,"textAnchor":551},"149.0","HTML cacheable and still in HTTP cache?",[51,867],{"x":831,"y":861,"width":821,"height":822,"rx":84,"fill":125,"stroke":125,"style":126},[74,869,870],{"x":834,"y":864,"fill":71,"style":101,"textAnchor":551},"Reload from HTTP cache — full startup work",[342,872],{"x1":838,"y1":873,"x2":840,"y2":873,"stroke":71,"strokeWidth":841,"style":842,"markerEnd":843},"144.5",[74,875,573],{"x":846,"y":876,"fill":125,"style":848,"textAnchor":551},"137.5",[342,878],{"x1":825,"y1":879,"x2":825,"y2":855,"stroke":71,"strokeWidth":841,"style":842,"markerEnd":843},"162.0",[74,881,858],{"x":855,"y":882,"fill":857,"style":848},"184.0",[51,884],{"x":76,"y":885,"width":821,"height":822,"rx":84,"fill":71,"stroke":71,"style":538},"198.0",[74,887,889],{"x":825,"y":888,"fill":71,"style":827,"textAnchor":551},"220.0","Subresources cached?",[51,891],{"x":831,"y":885,"width":821,"height":822,"rx":84,"fill":125,"stroke":125,"style":126},[74,893,894],{"x":834,"y":888,"fill":71,"style":101,"textAnchor":551},"Network for HTML, cache for assets",[342,896],{"x1":838,"y1":897,"x2":840,"y2":897,"stroke":71,"strokeWidth":841,"style":842,"markerEnd":843},"215.5",[74,899,573],{"x":846,"y":900,"fill":125,"style":848,"textAnchor":551},"208.5",[342,902],{"x1":825,"y1":903,"x2":825,"y2":904,"stroke":71,"strokeWidth":841,"style":842,"markerEnd":843},"233.0","267.0",[74,906,858],{"x":855,"y":907,"fill":857,"style":848},"255.0",[51,909],{"x":76,"y":910,"width":821,"height":77,"rx":84,"fill":85,"stroke":86,"style":87},"269.0",[74,912,914],{"x":825,"y":913,"fill":71,"style":101,"textAnchor":551},"290.5","Full network reload",[15,916,917],{},"The browser also evicts pages from bfcache after a time limit (minutes, varying by browser) and under memory pressure, so even eligible pages are not always restored. That is outside your control; eligibility is not.",[153,919,921],{"id":920},"advanced-diagnostics-and-edge-cases","Advanced Diagnostics and Edge Cases",[15,923,924,927],{},[167,925,926],{},"Single-page apps."," In-app back navigations within an SPA are not bfcache navigations at all — the router handles them. bfcache matters when the user leaves the SPA (to another site or a server-rendered page) and comes back.",[15,929,930,936],{},[167,931,932,933,935],{},"Pages with ",[31,934,37],{}," for authentication reasons."," Chrome has been relaxing this restriction in some circumstances, but you should not rely on it; separate sensitive pages from general ones.",[15,938,939,942,943,945],{},[167,940,941],{},"Cross-origin iframes."," An ad or embed iframe that holds an unload handler or open connection can block the whole page. ",[31,944,188],{}," lists blocked frames, sometimes masked for cross-origin frames.",[15,947,948,951,952,955,956,958],{},[167,949,950],{},"Broadcast channels and shared workers."," Open ",[31,953,954],{},"BroadcastChannel"," objects historically blocked bfcache; browser behaviour has improved, but closing channels on ",[31,957,685],{}," remains the safe pattern.",[15,960,961,964,965,310,967,969,970,972],{},[167,962,963],{},"Safari and Firefox."," Both have long had bfcache implementations with their own rules; the ",[31,966,289],{},[31,968,293],{}," pattern works in all three engines, while ",[31,971,188],{}," is Chromium-only.",[153,974,976],{"id":975},"validation-and-budgeting","Validation and Budgeting",[15,978,979,980,982,983,663],{},"Track the restoration rate per template in RUM and set a target (for example 75% of back\u002Fforward navigations in Chromium). Add a Puppeteer or Playwright check for key templates: navigate to the page, navigate away, go back, and assert that ",[31,981,289],{}," reported ",[31,984,985],{},"persisted: true",[331,987,989],{"className":333,"code":988,"language":335,"meta":336,"style":336},"\u002F\u002F playwright — assert a template is bfcache-eligible.\nawait page.goto('https:\u002F\u002Fstaging.example.com\u002Fsearch?q=boots');\nawait page.evaluate(() => addEventListener('pageshow', (e) => { window.__restored = e.persisted; }));\nawait page.goto('https:\u002F\u002Fstaging.example.com\u002Fabout');\nawait page.goBack();\nexpect(await page.evaluate(() => window.__restored)).toBe(true);\n\u002F\u002F trade-off: headless and automated browsers may apply different bfcache\n\u002F\u002F limits; treat a failure as a prompt to check DevTools' bfcache panel.\n",[31,990,991,996,1015,1054,1069,1081,1111,1116],{"__ignoreMap":336},[340,992,993],{"class":342,"line":343},[340,994,995],{"class":491},"\u002F\u002F playwright — assert a template is bfcache-eligible.\n",[340,997,998,1001,1004,1007,1009,1012],{"class":342,"line":375},[340,999,1000],{"class":368},"await",[340,1002,1003],{"class":350}," page.",[340,1005,1006],{"class":346},"goto",[340,1008,351],{"class":350},[340,1010,1011],{"class":354},"'https:\u002F\u002Fstaging.example.com\u002Fsearch?q=boots'",[340,1013,1014],{"class":350},");\n",[340,1016,1017,1019,1021,1024,1027,1029,1032,1034,1036,1038,1041,1043,1045,1048,1051],{"class":342,"line":407},[340,1018,1000],{"class":368},[340,1020,1003],{"class":350},[340,1022,1023],{"class":346},"evaluate",[340,1025,1026],{"class":350},"(() ",[340,1028,369],{"class":368},[340,1030,1031],{"class":346}," addEventListener",[340,1033,351],{"class":350},[340,1035,355],{"class":354},[340,1037,358],{"class":350},[340,1039,1040],{"class":361},"e",[340,1042,365],{"class":350},[340,1044,369],{"class":368},[340,1046,1047],{"class":350}," { window.__restored ",[340,1049,1050],{"class":368},"=",[340,1052,1053],{"class":350}," e.persisted; }));\n",[340,1055,1056,1058,1060,1062,1064,1067],{"class":342,"line":416},[340,1057,1000],{"class":368},[340,1059,1003],{"class":350},[340,1061,1006],{"class":346},[340,1063,351],{"class":350},[340,1065,1066],{"class":354},"'https:\u002F\u002Fstaging.example.com\u002Fabout'",[340,1068,1014],{"class":350},[340,1070,1071,1073,1075,1078],{"class":342,"line":431},[340,1072,1000],{"class":368},[340,1074,1003],{"class":350},[340,1076,1077],{"class":346},"goBack",[340,1079,1080],{"class":350},"();\n",[340,1082,1083,1086,1088,1090,1092,1094,1096,1098,1101,1104,1106,1109],{"class":342,"line":455},[340,1084,1085],{"class":346},"expect",[340,1087,351],{"class":350},[340,1089,1000],{"class":368},[340,1091,1003],{"class":350},[340,1093,1023],{"class":346},[340,1095,1026],{"class":350},[340,1097,369],{"class":368},[340,1099,1100],{"class":350}," window.__restored)).",[340,1102,1103],{"class":346},"toBe",[340,1105,351],{"class":350},[340,1107,1108],{"class":381},"true",[340,1110,1014],{"class":350},[340,1112,1113],{"class":342,"line":476},[340,1114,1115],{"class":491},"\u002F\u002F trade-off: headless and automated browsers may apply different bfcache\n",[340,1117,1118],{"class":342,"line":482},[340,1119,1120],{"class":491},"\u002F\u002F limits; treat a failure as a prompt to check DevTools' bfcache panel.\n",[15,1122,1123,1127],{},[19,1124,1126],{"href":1125},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache\u002Fmeasuring-bfcache-hit-rate-in-rum\u002F","Measuring bfcache hit rate in RUM"," covers the field side in depth.",[153,1129,1131],{"id":1130},"framework-and-library-considerations","Framework and Library Considerations",[15,1133,1134,1137,1138,1140,1141,1143],{},[167,1135,1136],{},"React, Vue and other SPAs."," Frameworks themselves do not block bfcache, but common companions do: analytics libraries that flush on ",[31,1139,33],{},", real-time data clients that keep WebSockets open, and state-persistence plugins that write to IndexedDB in ",[31,1142,313],{},". Audit these first; they are usually configurable.",[15,1145,1146,1149,1150,1152],{},[167,1147,1148],{},"Next.js and Nuxt."," Server-rendered pages from both frameworks are generally eligible. Watch for middleware or route handlers that set ",[31,1151,37],{}," on every HTML response by default — a common setting in authenticated apps that also affects public pages if applied globally.",[15,1154,1155,1158],{},[167,1156,1157],{},"Service workers."," A registered service worker does not prevent restoration. Pages controlled by a service worker are restored from bfcache like any other, without the service worker being involved.",[15,1160,1161,1167,1168,1171,1172,1175],{},[167,1162,1163,1166],{},[31,1164,1165],{},"window.opener"," relationships."," Pages opened with ",[31,1169,1170],{},"window.open()"," that keep a reference to their opener can be ineligible in some browsers. Use ",[31,1173,1174],{},"rel=\"noopener\""," on links that open new windows unless the relationship is required.",[15,1177,1178,1186,1187,1189,1190,1193,1194,689,1196,1198],{},[167,1179,1180,1183,1184,663],{},[31,1181,1182],{},"Cache-Control: no-cache"," vs ",[31,1185,671],{}," Only ",[31,1188,671],{}," affects eligibility in the cases browsers restrict; ",[31,1191,1192],{},"no-cache"," (revalidate before use) does not. Teams frequently use ",[31,1195,671],{},[31,1197,1192],{}," would serve their purpose.",[153,1200,1202],{"id":1201},"third-party-scripts-the-hidden-blockers","Third-Party Scripts: The Hidden Blockers",[15,1204,1205,1206,1208,1209,1211],{},"On sites that have cleaned up their own code, the remaining blockers are usually third parties. Older analytics snippets register ",[31,1207,33],{}," handlers to flush data; chat widgets keep WebSockets open; some ad iframes hold connections or unload handlers of their own. ",[31,1210,188],{}," identifies blocking frames, and DevTools often names the script.",[15,1213,1214,1215,1217,1218,1221,1222,1224,1225,1228,1229,663],{},"The options mirror any third-party performance problem: update to a vendor version that uses ",[31,1216,685],{}," or ",[31,1219,1220],{},"visibilitychange"," (most major vendors have shipped such fixes), configure the vendor to avoid the blocking API, load the vendor only on pages where it is needed, or replace it. Chrome has also been working towards deprecating ",[31,1223,33],{}," entirely, with a Permissions-Policy (",[31,1226,1227],{},"unload=()",") that lets a site disable unload handlers for itself and its iframes — a blunt but effective tool once you have confirmed nothing you rely on needs ",[31,1230,33],{},[331,1232,1236],{"className":1233,"code":1234,"language":1235,"meta":336,"style":336},"language-http shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","Permissions-Policy: unload=()\n","http",[31,1237,1238],{"__ignoreMap":336},[340,1239,1240],{"class":342,"line":343},[340,1241,1234],{},[15,1243,1244,1245,1247,1248,310,1250,1252,1253,1256],{},"The trade-off: any script — yours or a vendor's — that relied on ",[31,1246,33],{}," to send data will stop doing so. Make sure analytics use ",[31,1249,1220],{},[31,1251,685],{}," with ",[31,1254,1255],{},"sendBeacon"," before setting the policy.",[153,1258,1260],{"id":1259},"worked-example-a-listing-detail-flow","Worked Example: A Listing-Detail Flow",[15,1262,1263,1264,1266,1267,1269,1270,1272,1273,1275,1276,1278,1279,1281,1282,1284,1285,1287,1288,1290],{},"A marketplace's search results page had a bfcache restoration rate of 12% in Chromium field data. ",[31,1265,188],{}," showed three dominant causes: an ",[31,1268,33],{}," handler from an old analytics snippet (61% of misses), a WebSocket for live price updates (22%), and ",[31,1271,37],{}," on the HTML (17%, set globally by an authentication middleware). The team removed the analytics ",[31,1274,33],{}," in favour of ",[31,1277,1220],{}," + ",[31,1280,1255],{},", closed the WebSocket on ",[31,1283,685],{}," and reopened it on ",[31,1286,289],{},", and limited ",[31,1289,671],{}," to account pages. The restoration rate rose to 84%. Back navigations from product pages to results became effectively instant, scroll position and filters were preserved, and the share of sessions viewing three or more products increased by 9%.",[15,1292,1293],{},[42,1294,49,1297,49,1300,49,1303,49,1305,49,1308,49,1310,49,1314,49,1318,49,1322,49,1325,49,1328,49,1332,49,1335,49,1338,49,1342,49,1346,49,1349,49],{"viewBox":1295,"width":45,"role":46,"ariaLabel":1296,"style":48},"0 0 760 194","Bar chart of the share of back\u002Fforward navigations restored from bfcache as each blocker was removed on a search results page.",[51,1298],{"className":1299,"x":55,"y":55,"width":45,"height":45,"fill":56},[54],[58,1301,1302],{},"Worked example — bfcache restoration rate by fix",[62,1304,1296],{},[51,1306],{"x":66,"y":66,"width":67,"height":1307,"rx":69,"fill":70,"stroke":71,"style":72},"192",[74,1309,1302],{"x":76,"y":77,"fill":71,"style":78},[74,1311,1313],{"x":1312,"y":212,"fill":71,"style":213,"textAnchor":214},"230.5","Baseline",[51,1315],{"x":1316,"y":81,"width":1317,"height":220,"rx":221,"fill":85,"stroke":86,"style":236},"242.5","60.8",[74,1319,1321],{"x":1320,"y":212,"fill":71,"style":226},"309.3","12%",[74,1323,1324],{"x":1312,"y":230,"fill":71,"style":213,"textAnchor":214},"unload handler removed",[51,1326],{"x":1316,"y":234,"width":1327,"height":220,"rx":221,"fill":125,"stroke":125,"style":222},"288.7",[74,1329,1331],{"x":1330,"y":230,"fill":71,"style":226},"537.2","57%",[74,1333,1334],{"x":1312,"y":106,"fill":71,"style":213,"textAnchor":214},"+ WebSocket closed on pagehide",[51,1336],{"x":1316,"y":246,"width":1337,"height":220,"rx":221,"fill":125,"stroke":125,"style":222},"374.8",[74,1339,1341],{"x":1340,"y":106,"fill":71,"style":226},"623.3","74%",[74,1343,1345],{"x":1312,"y":1344,"fill":71,"style":213,"textAnchor":214},"163.0","+ no-store limited to account pages",[51,1347],{"x":1316,"y":864,"width":1348,"height":220,"rx":221,"fill":125,"stroke":125,"style":222},"425.5",[74,1350,1351],{"x":250,"y":1344,"fill":71,"style":226},"84%",[153,1353,1355],{"id":1354},"a-rollout-plan-for-improving-restoration-rate","A Rollout Plan for Improving Restoration Rate",[15,1357,1358],{},"Improving bfcache eligibility is low-risk, but it touches analytics, real-time features and security headers, so roll it out deliberately.",[649,1360,1361,1373,1385,1394,1403,1409],{},[164,1362,1363,1366,1367,1369,1370,1372],{},[167,1364,1365],{},"Instrument first."," Ship the ",[31,1368,289],{}," beacon with ",[31,1371,188],{}," for a week to get a ranked list of blockers per template. Without it, you will fix the reasons DevTools shows on your machine rather than the ones that matter in the field.",[164,1374,1375,1378,1379,1381,1382,1384],{},[167,1376,1377],{},"Fix first-party blockers."," Replace ",[31,1380,33],{}," handlers, close connections on ",[31,1383,685],{},", commit IndexedDB transactions promptly. These are code changes your team controls entirely.",[164,1386,1387,1390,1391,1393],{},[167,1388,1389],{},"Review headers."," Identify which templates genuinely need ",[31,1392,671],{},". Changing headers on authenticated pages needs a security review; changing them on public pages usually does not.",[164,1395,1396,1399,1400,1402],{},[167,1397,1398],{},"Tackle third parties."," Update vendor snippets, then consider the ",[31,1401,33],{}," Permissions-Policy once nothing depends on it.",[164,1404,1405,1408],{},[167,1406,1407],{},"Add freshness on restore."," Before announcing the change, make sure restored pages refresh anything time-sensitive, so instant back navigations never show a stale cart or expired session.",[164,1410,1411,1414],{},[167,1412,1413],{},"Lock it in."," Add the eligibility assertion to end-to-end tests for key templates and a restoration-rate alert to the RUM dashboard, so a new vendor or middleware change cannot silently undo the work.",[15,1416,1417],{},"Most teams complete steps 1–3 in a sprint and see the largest gains there; third-party work takes longer because it depends on vendors.",[153,1419,1421],{"id":1420},"why-bfcache-belongs-in-a-caching-strategy","Why bfcache Belongs in a Caching Strategy",[15,1423,1424,1425,1427,1428,1431],{},"bfcache is often discussed as a browser feature rather than a caching decision, but it interacts directly with the HTTP caching choices in the rest of this section. Headers you set for correctness — ",[31,1426,671],{}," on HTML, short ",[31,1429,1430],{},"max-age"," — determine both whether the page is bfcache-eligible and how expensive a fallback reload will be. Service workers do not interfere with bfcache restorations, but they shape the reload path. Edge-cached HTML makes reloads cheaper. Thinking about the three paths together — bfcache, HTTP cache, network — produces better decisions than tuning any of them alone, particularly for browse-heavy templates where back navigations are frequent.",[153,1433,1435],{"id":1434},"faq","FAQ",[1437,1438,1441,1445],"details",{"className":1439},[1440],"faq-item",[1442,1443,1444],"summary",{},"Does bfcache affect Core Web Vitals reporting?",[15,1446,1447,1448,1450,1451,1453],{},"Yes. Chrome reports bfcache restorations as separate page views in CrUX, with near-instant LCP, which improves your field distribution. The ",[31,1449,301],{}," library reports metrics for restored pages too (with ",[31,1452,297],{},"). More restorations means a better p75.",[1437,1455,1457,1460],{"className":1456},[1440],[1442,1458,1459],{},"Is it safe to restore pages with stale data?",[15,1461,1462,1463,1465],{},"Usually, with a refresh on return: restore instantly, then update anything time-sensitive (cart counts, prices, notifications) in a ",[31,1464,289],{}," handler. Users get an instant page and fresh data a moment later, which beats a slow reload.",[1437,1467,1469,1472],{"className":1468},[1440],[1442,1470,1471],{},"Do I need to do anything for bfcache to work?",[15,1473,1474],{},"Often nothing — many pages are eligible by default. You need to act when something on the page makes it ineligible, which is common on real-world sites because of third-party scripts and legacy unload handlers.",[1437,1476,1478,1481],{"className":1477},[1440],[1442,1479,1480],{},"How is bfcache different from the HTTP cache?",[15,1482,1483],{},"The HTTP cache stores responses (bytes); bfcache stores live pages (the whole document state in memory). An HTTP-cache hit still requires parsing, executing and rendering; a bfcache restore skips all of it.",[1437,1485,1487,1490],{"className":1486},[1440],[1442,1488,1489],{},"Do pages in bfcache keep running JavaScript?",[15,1491,1492],{},"No. Pages in bfcache are frozen: timers, promise callbacks and network activity are paused, and resume when the page is restored. That is why open connections are a problem — the browser cannot freeze them safely — and why timers may fire immediately after restoration if their deadline passed while frozen.",[1437,1494,1496,1499],{"className":1495},[1440],[1442,1497,1498],{},"How long do pages stay in bfcache?",[15,1500,1501],{},"Browsers keep only a few pages and evict them after a time limit (minutes, varying by browser and device memory) or under memory pressure. Eligibility is under your control; residence time mostly is not.",[1437,1503,1505,1508],{"className":1504},[1440],[1442,1506,1507],{},"Does bfcache work for pages behind a login?",[15,1509,1510,1511,1513,1514,1516],{},"It can. Authentication alone does not block restoration; what usually does is ",[31,1512,37],{}," added to authenticated responses, plus open connections for live data. If a restored authenticated page could show data after the user has logged out in another tab, check the session on ",[31,1515,289],{}," and redirect when it is no longer valid — that keeps the instant restore for the common case while protecting the rare one.",[1437,1518,1520,1523],{"className":1519},[1440],[1442,1521,1522],{},"Can I see bfcache restorations in Lighthouse?",[15,1524,1525,1526,1528],{},"Lighthouse includes a \"Page prevented back\u002Fforward cache restoration\" audit that runs a navigate-away-and-back test and lists failure reasons, which makes it a convenient CI signal. It tests one lab environment, so pair it with field data from ",[31,1527,188],{}," to catch blockers that only appear for some users, such as vendors loaded conditionally.",[153,1530,1532],{"id":1531},"guides-in-this-topic","Guides in This Topic",[161,1534,1535,1541,1547,1552,1557],{},[164,1536,1537,1540],{},[19,1538,1539],{"href":708},"Fixing bfcache eligibility blockers"," — work through the reasons DevTools reports.",[164,1542,1543,1546],{},[19,1544,1545],{"href":661},"Replacing unload handlers for bfcache"," — the most common blocker.",[164,1548,1549,1551],{},[19,1550,677],{"href":676}," — when the header is necessary and when it is not.",[164,1553,1554,1556],{},[19,1555,1126],{"href":1125}," — the field metric for this topic.",[164,1558,1559,1562],{},[19,1560,1561],{"href":701},"Restoring state on pageshow after bfcache"," — keeping restored pages fresh.",[153,1564,1566],{"id":1565},"related","Related",[161,1568,1569,1576,1583,1590],{},[164,1570,1571,1575],{},[19,1572,1574],{"href":1573},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fhttp-cache-control-headers-explained\u002F","HTTP Cache-Control headers explained"," — the header choices that affect eligibility.",[164,1577,1578,1582],{},[19,1579,1581],{"href":1580},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fservice-worker-caching-strategies\u002F","Service Worker caching strategies"," — the reload path when bfcache misses.",[164,1584,1585,1589],{},[19,1586,1588],{"href":1587},"\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002F","Speculative loading and prefetching"," — the forward-looking counterpart to instant back navigations.",[164,1591,1592,1596],{},[19,1593,1595],{"href":1594},"\u002Fcore-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fsending-web-vitals-with-sendbeacon-on-visibility-change\u002F","Sending web vitals with sendBeacon on visibility change"," — beacon timing that does not block bfcache.",[1598,1599,1601],"script",{"type":1600},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"Back\u002FForward Cache (bfcache): Making Back Navigations Instant\",\n  \"description\": \"How the browser's back\u002Fforward cache restores whole pages instantly, what blocks it, and how to make every page eligible.\",\n  \"step\": [\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 1,\n      \"name\": \"Environment Setup: Test Eligibility in DevTools\",\n      \"text\": \"Open the page, go to Application → Back\u002Fforward cache, and click \\\"Test back\u002Fforward cache\\\".\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 2,\n      \"name\": \"Capture a Baseline in the Field\",\n      \"text\": \"Measure what share of back\u002Fforward navigations are restored, and why the others are not.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 3,\n      \"name\": \"Isolate the Blocking Reasons\",\n      \"text\": \"Group field reasons by frequency.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 4,\n      \"name\": \"Apply the Fixes\",\n      \"text\": \"1.\"\n    }\n  ]\n}\n",[1598,1603,1604],{"type":1600},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"Back\u002FForward Cache (bfcache): Making Back Navigations Instant\",\n  \"description\": \"How the browser's back\u002Fforward cache restores whole pages instantly, what blocks it, and how to make every page eligible.\",\n  \"datePublished\": \"2026-10-06\",\n  \"dateModified\": \"2026-10-06\",\n  \"author\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"publisher\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"mainEntityOfPage\": {\n    \"@type\": \"WebPage\",\n    \"@id\": \"https:\u002F\u002Ffrontend-performance.com\u002Fadvanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache\u002F\"\n  }\n}\n",[1598,1606,1607],{"type":1600},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 1,\n      \"name\": \"Home\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 2,\n      \"name\": \"Advanced Caching Strategies & CDN Architecture\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fadvanced-caching-strategies-cdn-architecture\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 3,\n      \"name\": \"Back\u002FForward Cache (bfcache)\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fadvanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache\u002F\"\n    }\n  ]\n}\n",[1609,1610,1611],"style",{},"html pre.shiki code .smZ65, html code.shiki .smZ65{--shiki-default:#622CBC;--shiki-dark:#DBB7FF;--shiki-light:#622CBC}html pre.shiki code .saISM, html code.shiki .saISM{--shiki-default:#0E1116;--shiki-dark:#F0F3F6;--shiki-light:#0E1116}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}html pre.shiki code .sQw3B, html code.shiki .sQw3B{--shiki-default:#702C00;--shiki-dark:#FFB757;--shiki-light:#702C00}html pre.shiki code .sPARh, html code.shiki .sPARh{--shiki-default:#A0111F;--shiki-dark:#FF9492;--shiki-light:#A0111F}html pre.shiki code .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .sjfSM, html code.shiki .sjfSM{--shiki-default:#66707B;--shiki-dark:#BDC4CC;--shiki-light:#66707B}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}",{"title":336,"searchDepth":375,"depth":375,"links":1613},[1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630],{"id":155,"depth":375,"text":156},{"id":254,"depth":375,"text":255},{"id":318,"depth":375,"text":319},{"id":325,"depth":375,"text":326},{"id":510,"depth":375,"text":511},{"id":646,"depth":375,"text":647},{"id":712,"depth":375,"text":713},{"id":920,"depth":375,"text":921},{"id":975,"depth":375,"text":976},{"id":1130,"depth":375,"text":1131},{"id":1201,"depth":375,"text":1202},{"id":1259,"depth":375,"text":1260},{"id":1354,"depth":375,"text":1355},{"id":1420,"depth":375,"text":1421},{"id":1434,"depth":375,"text":1435},{"id":1531,"depth":375,"text":1532},{"id":1565,"depth":375,"text":1566},"How the browser's back\u002Fforward cache restores whole pages instantly, what blocks it, and how to make every page eligible.","md",{"slug":1634,"type":1635,"breadcrumb":1636,"datePublished":1642,"dateModified":1642},"back-forward-cache-bfcache","topic",[1637,1639,1640],{"name":1638,"url":310},"Home",{"name":22,"url":21},{"name":5,"url":1641},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache\u002F","2026-10-06",true,"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache",{"title":1646,"description":1647},"Back\u002FForward Cache (bfcache): Instant Back Navigations","Make back and forward navigations instant with the bfcache: find eligibility blockers, replace unload handlers, handle no-store and restore state on pageshow.","advanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache\u002Findex","si35Zrvsvkt4zwkuE4kzdH1e3uaLXpxF2H4Lx7eRclw",[1651,1654],{"title":22,"path":1652,"stem":1653},"\u002Fadvanced-caching-strategies-cdn-architecture","advanced-caching-strategies-cdn-architecture\u002Findex",{"title":677,"path":1655,"stem":1656},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache\u002Fcache-control-no-store-and-bfcache","advanced-caching-strategies-cdn-architecture\u002Fback-forward-cache-bfcache\u002Fcache-control-no-store-and-bfcache\u002Findex",1791308070325]