JavaScript BFCache (Back/Forward Cache) 上下頁/往返 快取
BFCache (Back/Forward Cache) 是一種瀏覽器優化技術,旨在讓使用者在點擊「上一頁」或「下一頁」時能實現「瞬間載入」。與傳統的 HTTP 快取不同,BFCache 會將整個頁面的完整狀態(包含 JavaScript 執行狀態、DOM 現狀等)保留在記憶體中。
當頁面從 BFCache 恢復時,它不需要重新下載資源或重新解析 HTML,而是直接從記憶體中還原,這對提升使用者體驗有極大的幫助。
BFCache 的工作原理
當使用者導向新頁面時,支援 BFCache 的瀏覽器不會銷毀目前的頁面,而是將其「凍結」並存入快取。
- 暫停執行: 所有的定時器 (
setTimeout)、正在進行的網路請求或動畫都會被暫停。 - 狀態保留: 所有變數的值、輸入框的文字、捲動軸的位置都會被原封不動地保存。
- 恢復執行: 當使用者回到該頁面時,瀏覽器只需將頁面「恢復」,JavaScript 會從剛才暫停的地方繼續執行。
如何檢測頁面是否來自 BFCache?
由於 BFCache 恢復時不會觸發 load 事件,開發者必須使用 pageshow 事件,並檢查 event.persisted 屬性。
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
console.log('此頁面是從 BFCache 恢復的');
// 在這裡更新過時的資訊,例如購物車數量或登入狀態
} else {
console.log('此頁面是全新載入的');
}
});
同理,當頁面進入 BFCache 時,會觸發 pagehide 事件:
window.addEventListener('pagehide', (event) => {
if (event.persisted) {
console.log('頁面即將進入 BFCache');
} else {
console.log('頁面即將被正常卸載');
}
});
影響 BFCache 成功率的因素
瀏覽器非常希望能將頁面存入 BFCache,但有些開發者的行為會阻止這項優化:
1. 絕對避免使用 unload 事件
這是最常見的錯誤。只要頁面註冊了 unload 監聽器,瀏覽器為了安全起見(擔心卸載邏輯沒跑完),通常會直接禁用該頁面的 BFCache。
- 建議做法: 使用
pagehide取代unload來處理資料清理或分析統計。
2. Cache-Control: no-store 的改變
過去,設定 Cache-Control: no-store 的頁面會被強制禁用 BFCache。
- 最新趨勢: 2025 年起,Chrome 等瀏覽器開始嘗試在「安全」的情況下讓
no-store頁面也能進入 BFCache,以追求極致效能。但如果頁面包含極度敏感的個人資料(如銀行餘額),仍應謹慎使用。
3. 未關閉的連接
如果頁面在隱藏前仍開著 WebSocket、WebRTC 或連線中的 IndexedDB 事務,可能會導致 BFCache 失敗。
- 建議做法: 在
pagehide或visibilitychange發生時主動關閉這些連線。
4. 使用了 window.opener
如果頁面是透過 window.open 開啟且保留了對原頁面的引用,也可能影響快取。
最佳實踐建議
- 更新敏感資料: 既然頁面是從記憶體快照恢復的,上面的資料可能是數小時前的。務必在
pageshow事件中重新整理時間、認證狀態或最新動態。 - 清理任務: 使用
pagehide停止正在運行的動畫或不必要的計時器。 - 使用 DevTools 測試:
- 打開 Chrome DevTools -> Application 選項卡。
- 點擊左側的 Back/forward cache。
- 點擊 Test back/forward cache,它會自動測試並告訴你為什麼你的頁面無法進入快取。
透過優化 BFCache,你可以讓網站的導覽感受提升到另一個層次,減少等待時間並增加使用者留存率。
相關閱讀: