Bộ nhớ đệm Back/Forward (bfcache)

Back/forward cache đóng băng toàn bộ trang trong bộ nhớ để khôi phục tức thì khi Back/Forward. Tìm hiểu điểm khác HTTP cache, điều kiện, rào cản, cách kiểm thử và mối liên hệ gián tiếp với Core Web Vitals.

Xuất bản lần đầu: 3 thg 7, 2026 · Cập nhật lần cuối: 9 thg 8, 2026 · Advanced
Ngôn ngữ

Back/forward cache (bfcache) là tính năng trình duyệt đóng băng toàn bộ trang — DOM, JavaScript heap và trạng thái đang chạy — trong bộ nhớ để có thể khôi phục gần như tức thì khi người dùng Back hoặc Forward, miễn là ảnh chụp chưa bị loại. Đây không phải HTTP cache, resource cache, Cache Storage hay yếu tố xếp hạng Google. Tác động SEO chỉ gián tiếp: lượt được khôi phục có LCP gần như tức thì và gần như không thêm CLS, nhưng không bảo đảm tỷ lệ khôi phục, Core Web Vitals tổng hợp, thứ hạng hay chuyển đổi. Rào cản lớn nhất là trình xử lý unload; Cache-Control: no-store từng là nguyên nhân lịch sử lớn nhất, nhưng Chrome từ đợt triển khai tháng 3–4/2025 cho phép có điều kiện nhiều trang no-store. Kiểm thử bằng Chrome DevTools và chẩn đoán dữ liệu thực tế bằng notRestoredReasons trên Chrome 123+.

Tóm tắt — Bfcache là ảnh chụp toàn trang trong bộ nhớ — DOM + JS heap + trạng thái đang chạy — không phải phản hồi HTTP có thể tải lại, resource cache trong bộ nhớ hay Cache Storage của service worker. Khi điều hướng khỏi trang, trình duyệt tạm dừng JS và đóng băng trang; khi Back/Forward, nếu ảnh chụp vẫn còn, trình duyệt kích hoạt và hiển thị lại tức thì mà không gửi request mạng. Tuy nhiên, ảnh chụp luôn có thể bị loại, nên khôi phục là khả năng chứ không phải bảo đảm. Bfcache không phải yếu tố xếp hạng Google Search được ghi nhận; liên quan SEO chỉ gián tiếp qua số liệu CWV thực tế — chủ yếu LCP và CLS — trên lượt điều hướng thực sự được khôi phục, không bảo đảm tỷ lệ khôi phục, CWV tổng hợp, thứ hạng hay chuyển đổi. Trình xử lý unload là rào cản điều kiện lớn nhất — làm giảm khoảng 18 điểm phần trăm tỷ lệ hit trên Chrome. Cache-Control: no-store từng là nguyên nhân lịch sử lớn nhất — chặn khoảng 17% lượt điều hướng lịch sử trên mobile và 7% trên desktop — nhưng sau đợt triển khai năm 2025, Chrome cho phép có điều kiện nhiều trang no-store: trang bị loại khi trạng thái xác thực/cookie thay đổi và vẫn bị chặn bởi các API kết nối mở. Hãy đóng hoặc tạm dừng kết nối, timer và observer tại pagehide/freeze, rồi thiết lập lại tại pageshow/resume. window.opener, permissions policy và frame cũng có thể chặn; hãy xem lý do theo từng frame trong DevTools hoặc notRestoredReasons. Kiểm thử riêng lẻ bằng Chrome DevTools; chẩn đoán thực tế bằng API notRestoredReasons chỉ có trên Chrome — giá trị null không chứng minh đã khôi phục và văn bản lý do không ổn định. Mỗi trình duyệt có quy tắc riêng, còn soft navigation của SPA không được xử lý tương tự.

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 thực chất là gì — trục chính về độ chính xác

Điểm quan trọng nhất: bfcache là ảnh chụp toàn trang trong bộ nhớ, không phải phản hồi HTTP được lưu đệm. Khi bạn điều hướng khỏi trang, thay vì hủy trang, trình duyệt tạm dừng JavaScript và đóng băng toàn bộ trạng thái — DOM, JS heap, timer đang chạy và mọi phần còn lại — trong bộ nhớ. Nếu bạn nhấn Back hoặc Forward khi ảnh chụp vẫn còn, trình duyệt kích hoạt lại và hiển thị đúng trang đã rời đi, với không request mạng và không kết xuất lại. Đây là khả năng khôi phục, không phải bảo đảm: trình duyệt có thể loại ảnh chụp do áp lực bộ nhớ, hết thời gian hay sự kiện nhất định; quy tắc riêng của trình duyệt cũng có thể buộc tải mới. Google mô tả bfcache là “a browser optimization that enables instant back and forward navigation.” (bản dịch) “một cơ chế tối ưu hóa trình duyệt cho phép điều hướng quay lại và tiến tới tức thì.”

Đây là lý do việc đánh đồng bfcache với HTTP/browser cache là lỗi lặp lại trong nội dung đối thủ. HTTP cache lưu phản hồi của các request trước — các tệp có thể phục vụ lại. Bfcache lưu trang đang hoạt động. Tài liệu Chrome DevTools phân biệt rõ: bfcache “differs from browser cache and HTTP cache.” (bản dịch) “khác với browser cache và HTTP cache.” Bạn không “bật” bfcache bằng cache header như khi cấu hình HTTP caching; header chỉ liên quan vì Cache-Control: no-store từng khiến trang không đủ điều kiện — xem phần dưới.

Sự phân biệt tương tự áp dụng với hai cache khác thường bị nhầm với bfcache: resource cache trong bộ nhớ của trình duyệt — script đã biên dịch và hình ảnh đã giải mã trong phiên hiện tại — và Cache Storage của service worker — các cặp request/response mà website tự quản lý qua caches.open(). Cả hai có thể cùng hoạt động với bfcache trên một trang, nhưng không cơ chế nào bfcache; bfcache chính là phiên bản trang đóng băng, không phải asset được cache hay phản hồi bị chặn.

Cần phân biệt thêm vì vẫn thường gây nhầm: bfcache không liên quan tới tính năng “cached page” cũ trong tìm kiếm mà Google và Bing từng hiển thị trong kết quả. Đó là ảnh chụp trang được lưu trong chỉ mục tìm kiếm và đã ngừng hoạt động. Bfcache là tính năng phía client của rendering engine.

Lượt điều hướng Back/Forward phổ biến đến mức nào?

Đây không phải trường hợp hiếm. Theo web.dev, “1 in 10 navigations on desktop and 1 in 5 on mobile are either back or forward.” (bản dịch) “cứ 10 lượt điều hướng trên desktop có 1 lượt và cứ 5 lượt trên mobile có 1 lượt là quay lại hoặc tiến tới.” Với website có luồng lặp lại — từ danh mục thương mại điện tử tới sản phẩm rồi quay lại, kết quả tìm kiếm, nội dung phân trang hoặc đọc liên tiếp nhiều bài — đây là tỷ lệ lớn các lượt điều hướng thực có thể trở nên gần như tức thì.

Hỗ trợ trình duyệt

“All major browsers include a bfcache, including Chrome since version 96, Firefox and Safari.” (bản dịch) “Mọi trình duyệt lớn đều có bfcache, gồm Chrome từ phiên bản 96, Firefox và Safari.” Firefox và Safari đã có triển khai bfcache riêng lâu hơn; mọi trình duyệt dựa trên Chromium — Edge, Brave, Opera, Arc — thừa hưởng triển khai của Chrome. Tài liệu policy của Microsoft Edge mô tả cùng tính năng: khi rời trang, trạng thái hiện tại — cây tài liệu, script và các phần khác — có thể được giữ trong back-forward cache; nếu quay lại, trang có thể được khôi phục và hiển thị ở trạng thái trước khi cache. Edge bật mặc định; chỉ quản trị viên CNTT mới có thể tắt bằng enterprise policy, không phải chủ website.

Lưu ý quan trọng: bfcache của mỗi trình duyệt có quy tắc đủ điều kiện riêng. Trang vượt qua “Test back/forward cache” trong Chrome DevTools không được bảo đảm đủ điều kiện trên Firefox hoặc Safari. Hãy coi việc pass trên Chrome là cần thiết, chưa phải đầy đủ.

Những yếu tố chặn điều kiện bfcache

Sự kiện unload — rào cản lớn nhất

Nếu chỉ nhớ một điều từ bài này: hãy ngừng dùng sự kiện unload. web.dev nhấn mạnh hiếm thấy trong tài liệu Google: “Never use the unload event. Ever!” (bản dịch) “Đừng bao giờ dùng sự kiện unload.” Trên Chrome, trình xử lý unload làm giảm khoảng 18 điểm phần trăm tỷ lệ hit bfcache — rào cản do chính website gây ra lớn nhất.

Chrome đang chủ động ngừng hỗ trợ vì hai lý do. Thứ nhất, đây là rào cản bfcache lớn nhất. Thứ hai, bản thân unload cực kỳ thiếu tin cậy: trên mobile, sự kiện thường hoàn toàn không kích hoạt vì tab chuyển nền rồi bị đóng và trình duyệt ưu tiên bfcache hơn kích hoạt unload. Vì vậy sự kiện được dựa vào để “dọn dẹp” thường không chạy, đồng thời chặn một cải thiện hiệu suất thật.

Cách khắc phục:

  • Thay unload bằng pagehide. Sự kiện pagehide kích hoạt trong mọi trường hợp unload kích hoạt, và cả khi trang đi vào bfcache, nên đây là nâng cấp rõ ràng. Dùng visibilitychange để dọn dẹp đáng tin cậy khi “người dùng rời đi”.
  • Phát hiện lượt khôi phục bfcache bằng pageshow. Lắng nghe pageshow và kiểm tra event.persisted; nếu là true, trang đã được khôi phục từ bfcache — lúc đó hãy làm mới dữ liệu cũ hoặc đếm lại pageview.
  • Chủ động chặn listener unload bằng response header Permissions-Policy: unload=(), ngăn mọi trình xử lý unload được đăng ký. Chrome đang dần chuyển policy mặc định sang từ chối — Permissions-Policy cho unload có từ Chrome 115.

Cache-Control: no-store — lớn nhất trong lịch sử, nay cần hiểu có điều kiện

Đây là điểm về độ mới mà phần lớn nội dung đối thủ diễn đạt sai. Trong lịch sử, Cache-Control: no-storenguyên nhân đơn lẻ lớn nhất khiến trang bị loại khỏi bfcache — số liệu của Chrome ước tính khoảng 17% lượt điều hướng lịch sử trên mobile và 7% trên desktop. Nhiều website đặt no-store để tránh phục vụ trang cũ, nhưng Google lập luận lý do này yếu hơn với bfcache: lượt khôi phục bfcache không tải một phản hồi cũ được cache, mà hiển thị lại đúng trang đang hoạt động gần như thể tab vẫn mở.

Vì vậy Chrome đã thay đổi hành vi — có điều kiện, không phải phổ quát. Thử nghiệm bắt đầu ở Chrome 116 và triển khai hoàn tất cho 100% người dùng trong tháng 3 và tháng 4/2025. Chrome nay cho phép bfcache với nhiều trang no-store theo các điều kiện an toàn cụ thể, không phải ngoại lệ chung. Theo tài liệu Chrome, trang bị loại khỏi bfcache nếu trạng thái xác thực hoặc cookie thay đổi khi đang đóng băng; một khách đã đăng xuất hoặc xóa cookie sẽ không thấy ảnh chụp đăng nhập cũ. Danh sách API cố định — gồm các API kết nối mở như IndexedDB, WebSocket, WebRTC và những API dưới đây — vẫn loại trang no-store khỏi bfcache. Đây là hành vi riêng của Chrome trên một dải phiên bản cụ thể, không thể mặc định áp dụng cho trình duyệt khác hay Chrome cũ. Hãy lấy báo cáo DevTools/notRestoredReasons hiện tại trên đúng trình duyệt và phiên bản đang kiểm thử. Kết luận thực tế: hướng dẫn coi no-store là rào cản bfcache vô điều kiện và vĩnh viễn đã lỗi thời; coi vấn đề đã giải quyết hoàn toàn cũng sai. Nếu độ mới thực sự quan trọng, tài liệu Chrome đề xuất no-cache hoặc max-age ngắn — ví dụ max-age=60 — thay cho no-store.

Kết nối mở, observer và các rào cản khác

Tại thời điểm điều hướng, một số tài nguyên đang mở vẫn có thể chặn điều kiện — nhưng chính xác tài nguyên nào chặn hoàn toàn hay chỉ bị đóng rồi có thể kết nối lại phụ thuộc trình duyệt và phiên bản. Hãy coi danh sách dưới đây là ví dụ về một mô hình, không phải danh sách rào cản cố định, vĩnh viễn:

  • Request fetch() / XMLHttpRequest đang thực hiện.
  • Transaction IndexedDB đang mở.
  • Kết nối WebSocket / WebRTC, timer và observer đang mởMutationObserver, IntersectionObserver và tương tự. Lĩnh vực này tiếp tục cải thiện: ghi chú phát hành Microsoft Edge gần đây cho biết WebSocket mở nay bị đóng khi trang đi vào bfcache — thay vì chặn cache hoàn toàn — và khuyến nghị kết nối lại qua kiểm tra event.persisted của pageshow. Điều này phản ánh xu hướng rộng hơn của Chrome là giảm rào cản thay vì loại trang.

Mô hình tổng quát nên triển khai thay vì ghi nhớ danh sách cố định: đóng hoặc tạm dừng kết nối, timer và observer trong xử lý pagehide/freeze, rồi thiết lập lại trong xử lý pageshow/resume khi event.persisted là true. Mô hình này vẫn đúng khi trình duyệt thay đổi API nào chặn hoàn toàn và API nào chỉ bị tạm dừng rồi cho phép kết nối lại.

window.opener, permissions policy và frame. Tham chiếu window.opener, một số permissions policy và iframe nhúng — cùng origin hoặc khác origin — cũng có thể ảnh hưởng điều kiện; đây là mục trong checklist tôi đúc kết ở hướng dẫn CLS của Ahrefs và tài liệu Chrome. Đừng đoán nguyên nhân từ checklist chung: panel DevTools và API notRestoredReasons đều báo lý do chặn theo từng frame — top frame và từng iframe riêng — vì frame gây chặn không phải lúc nào cũng là trang cấp cao nhất. Hãy lấy lý do thật từ báo cáo theo frame trên trình duyệt đang kiểm thử.

Hiểu đúng chuỗi sự kiện và trạng thái vòng đời

Nhầm lẫn giữa điều mỗi sự kiện vòng đời thật sự chứng minh và điều nó chỉ gợi ý là lỗi chính xác phổ biến thứ hai, sau các lỗi về điều kiện ở trên:

Sự kiện / trạng tháiTín hiệuÝ nghĩa thựcViệc cần làm
pagehide (event.persisted === true)Ý định cacheTrình duyệt đang cố gắng đóng băng trang cho bfcache — chưa xác nhận đã vào cacheĐóng/tạm dừng kết nối, timer và observer tại đây; đừng mặc định trang sẽ được khôi phục
freezeĐã tạm dừngJS đã tạm dừng; trang vẫn có thể bị loại trước khi khôi phụcKhông cần làm thêm ngoài xử lý tại pagehide
Có thể bị loại mà không có sự kiệnTrình duyệt có thể bỏ trang đóng băng bất kỳ lúc nào do áp lực bộ nhớ, hết thời gian hoặc quy tắc riêng; không có sự kiện cho việc nàyĐừng dựa vào mã dọn dẹp chạy sau; luôn thực hiện tại pagehide/freeze
pageshow (event.persisted === true)Xác nhận khôi phụcTín hiệu đáng tin cậy duy nhất rằng lượt khôi phục bfcache thật sự xảy raLàm mới trạng thái nhạy cảm/theo thời gian, kết nối lại và đếm đúng một analytics view
resumeĐã tiếp tụcJS tiếp tục chạy sau lượt khôi phục được xác nhậnKết nối lại mọi thứ đã tạm dừng tại freeze

Quy tắc thực tế: coi pagehide.persistedý định, không phải bằng chứng — trang vẫn có thể bị loại trước khi được khôi phục. Chỉ pageshow.persisted === true mới chứng minh lượt khôi phục đã xảy ra. Luôn dọn dẹp tại pagehide/freeze — việc này rẻ và an toàn cả trên lượt điều hướng bình thường — và chỉ chạy tác vụ dành riêng cho khôi phục tại pageshow/resume, với điều kiện event.persisted, để không làm mới dữ liệu hay đếm analytics view hai lần khi tải mới thông thường.

Cách kiểm thử và chẩn đoán bfcache

Lab / kiểm tra một lần: Chrome DevTools

Mở DevTools → Application → Background services → Back/forward cache, rồi nhấp “Test back/forward cache.” Chrome tự điều hướng tới chrome://terms/ rồi quay lại, sau đó báo thành công hoặc danh sách lý do chặn cụ thể. Cách này phù hợp để kiểm tra từng URL.

Dữ liệu thực tế / production: API notRestoredReasons

Trước đây, cách duy nhất để kiểm tra điều kiện là bài test DevTools thủ công từng URL; không thể biết vì sao lượt điều hướng của người dùng thật bị chặn. Thuộc tính notRestoredReasons trên PerformanceNavigationTiming — có từ Chrome 123+ — lấp khoảng trống đó bằng cách báo lý do chặn cụ thể cho top frame và iframe cùng origin trong dữ liệu thực tế.

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

Một số điểm cần hiểu đúng theo hướng dẫn API của Chrome:

  • Chỉ có trên Chrome 123+. Firefox và Safari không cung cấp API thực tế tương đương, nên vẫn phải kiểm tra thủ công trên các trình duyệt đó để biết tỷ lệ khôi phục.
  • Kết quả null mơ hồ, không phải tín hiệu xanh. Nó có thể nghĩa là trang được khôi phục, hoặc trình duyệt không thu thập lý do; tài liệu Chrome nói không được coi null là bằng chứng khôi phục thành công.
  • Văn bản lý do không phải hợp đồng ổn định. Đừng hard-code so khớp chuỗi; hãy nhóm và theo dõi xu hướng theo lý do vì cách diễn đạt có thể đổi giữa các phiên bản Chrome.

Trong thực tế, hãy thu thập notRestoredReasons cùng tỷ lệ khôi phục pageshow.persisted trước và sau khi phát hành bản sửa, so sánh xu hướng thay vì một ảnh chụp, đồng thời kiểm tra lab thủ công trên Firefox và Safari. Đây là công cụ chẩn đoán bfcache ở quy mô RUM/production thay vì kiểm từng URL, nhưng không đại diện toàn bộ bức tranh.

Bfcache và Core Web Vitals — mối quan hệ chính xác

Đây là sắc thái phần lớn nội dung đối thủ làm mờ và là góc đáng trình bày rõ.

Cách đo lượt khôi phục bfcache. Trình duyệt — và do đó dữ liệu thực tế CrUX — tính một lượt điều hướng được khôi phục từ bfcache như lần “tải trang” cực nhanh: LCP gần như tức thì và, khi trang được triển khai đúng — không phải bố trí lại — gần như không có CLS bổ sung, vì không kết xuất lại. Trong so sánh thực tế của DebugBear, trang khôi phục từ bfcache có LCP khoảng 100ms so với ~427ms khi tải không cache. Đây là lý do bfcache xuất hiện như đòn bẩy CLS và LCP trong checklist CLS của Ahrefs, nơi tôi viết: “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.” (bản dịch) “Hãy bảo đảm trang đủ điều kiện dùng bfcache. Back/forward cache giữ trang trong cache trình duyệt, cho phép tải tức thì trang đã tải trước đó, nên không xảy ra dịch chuyển bố cục.”

Có hai giới hạn phạm vi cần nói chính xác. Thứ nhất, tác động chỉ áp dụng cho lượt điều hướng CrUX phân loại là back/forward — chiều navigation-type — không nói gì về lượt truy cập đầu hay tải lại, vốn chiếm phần lớn lưu lượng trên nhiều website. Thứ hai, cải thiện trải nghiệm được đo cho người nhận lượt khôi phục không phải bảo đảm: người dùng có trang bị loại khỏi bfcache vẫn nhận lần tải bình thường. Vì vậy công việc về điều kiện bfcache thay đổi tỷ lệ khôi phục trong các lượt Back/Forward, không phải tỷ lệ cố định của tổng lưu lượng; nó cũng không bảo đảm Core Web Vitals thực tế tổng hợp, thứ hạng hay tỷ lệ chuyển đổi. Đây là đòn bẩy thật, đo được nhưng có phạm vi cụ thể, không phải bản sửa hiệu suất hoặc SEO chung.

Bfcache có phải yếu tố xếp hạng không? Không. Đây là tuyên bố có thể bảo vệ và tạo khác biệt. Tài liệu xếp hạng Core Web Vitals của Google không nhắc bfcache. Chuỗi ảnh hưởng trung thực là: điều kiện bfcache → số liệu CWV thực tế tốt hơn — chủ yếu LCP/CLS — trên lượt Back/Forward → Core Web Vitals là một trong nhiều tín hiệu “trải nghiệm trang” mà Google nói phù hợp với điều hệ thống xếp hạng vốn tưởng thưởng. Tuyên bố này yếu hơn và chính xác hơn nhiều so với “bfcache tăng thứ hạng”. Bfcache cũng là tính năng rendering engine, không phải tính năng crawler; nó không liên quan cách Googlebot hay Bingbot crawl trang, nên không có “quan điểm của Bing về bfcache cho SEO” như với robots.txt hoặc sitemap.

SPA và soft navigation. Bfcache hoạt động trên điều hướng trình duyệt và sự kiện lịch sử thật. Thay đổi route “mềm” phía client của single-page app — hoán đổi view bằng JS mà không kích hoạt điều hướng trình duyệt thật — không phải sự kiện bfcache và không được xử lý tương tự. Việc một số công cụ RUM cố gán Core Web Vitals cho soft navigation có thể tạo sai khác giữa CrUX và RUM; đây là điểm cần lưu ý khi kiểm tra website dùng framework JS.

Rào cản bfcache phổ biến ngoài thực tế đến đâu?

Web Almanac của HTTP Archive theo dõi vấn đề này; đây là lĩnh vực đang thay đổi, không phải chuyện cũ đã ổn định. Bản 2022 cho biết ít nhất khoảng 22% trang mobile không đủ điều kiện bfcache chỉ theo hai tiêu chí unload và no-store. Từ đó, việc dùng trình xử lý unload giảm trên các nhóm website và thiết bị, nhưng Cache-Control: no-store lại tăng — chương 2025 ước tính khoảng 23% website, tăng từ khoảng 21% năm 2024, một phần do trải nghiệm xác thực/cá nhân hóa nhiều hơn và yêu cầu tuân thủ nghiêm ngặt hơn.

Phát hiện trái trực giác đáng trích dẫn: website lớn, lưu lượng cao có khả năng tự chặn bfcache cao hơn rõ rệt. Trong 1 000 website hàng đầu, khoảng 28% trang desktop và 20% trang mobile vẫn dùng trình xử lý unload, so với chỉ khoảng 11% desktop và 10% mobile trên toàn bộ website — thường vì website lớn mang nhiều analytics cũ và mã phụ thuộc unload. Những website có nhiều lưu lượng Back/Forward nhất để mất lại thường đang tự cản trở.

Vị trí của chủ đề này

Bfcache là một trong nhiều đòn bẩy hiệu suất trong cụm này. Lợi ích xuất hiện trong dữ liệu thực tế Core Web Vitals — cụ thể Cumulative Layout ShiftLargest Contentful Paint — vì trang được khôi phục hiển thị tức thì mà không bố trí lại. Cơ chế này khác caching, vốn lưu tệp thay vì ảnh chụp trang đang hoạt động, dù cả hai cùng có điểm liên quan là header Cache-Control. Không có liên hệ trực tiếp với Interaction to Next Paint, nên tôi không gượng ép kết nối.

Add an expert note

Pin an expert quote

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