API bộ nhớ đệm cho thao tác tiến/lùi không được khôi phục

Tìm những thao tác điều hướng bị chặn sử dụng bfcache và lý do.

Thuộc tính notRestoredReasons, được thêm vào lớp PerformanceNavigationTiming, báo cáo thông tin về việc các khung hình có trong tài liệu có bị chặn sử dụng bfcache khi điều hướng hay không và lý do. Nhà phát triển có thể sử dụng thông tin này để xác định những trang cần được cập nhật để tương thích với bfcache, từ đó cải thiện hiệu suất trang web.

Trạng thái hiện tại

API notRestoredReasons đã được phát hành từ Chrome 123 và đang được triển khai dần.

Khái niệm và cách sử dụng

Các trình duyệt hiện đại cung cấp một tính năng tối ưu hoá cho hoạt động điều hướng trong nhật ký, được gọi là bộ nhớ đệm cho thao tác tiến/lùi (bfcache). Điều này giúp người dùng có trải nghiệm tải tức thì khi quay lại một trang mà họ đã truy cập. Các trang có thể bị chặn truy cập vào bộ nhớ đệm chuyển tiếp/quay lại hoặc bị loại bỏ khi đang ở trong bộ nhớ đệm chuyển tiếp/quay lại vì nhiều lý do, một số lý do theo quy cách và một số lý do dành riêng cho việc triển khai trình duyệt.

Trước đây, nhà phát triển không thể biết lý do trang của họ bị chặn sử dụng bộ nhớ đệm chuyển tiếp trong trường, mặc dù có một thử nghiệm trong công cụ cho nhà phát triển Chrome. Để bật tính năng giám sát tại hiện trường, lớp PerformanceNavigationTiming đã được mở rộng để bao gồm thuộc tính notRestoredReasons. Thao tác này sẽ trả về một đối tượng chứa thông tin liên quan về khung hình trên cùng và tất cả iframe có trong tài liệu:

  • Lý do khiến họ không thể sử dụng bfcache.
  • Các thông tin chi tiết như khung idname, để giúp xác định iframe trong HTML.

    Điều này cho phép nhà phát triển hành động để các trang đó tương thích với bfcache, từ đó cải thiện hiệu suất trang web.

Ví dụ

Bạn có thể lấy một thực thể PerformanceNavigationTiming từ các đối tượng như Performance.getEntriesByType()PerformanceObserver.

Ví dụ: bạn có thể gọi hàm sau để trả về tất cả các đối tượng PerformanceNavigationTiming có trong dòng thời gian hiệu suất và ghi lại notRestoredReasons của các đối tượng đó:

function returnNRR() {
  const navEntries = performance.getEntriesByType("navigation");
  for (let i = 0; i < navEntries.length; i++) {
    console.log(`Navigation entry ${i}`);
    let navEntry = navEntries[i];
    console.log(navEntry.notRestoredReasons);
  }
}

Đối với các thao tác điều hướng trong nhật ký, thuộc tính PerformanceNavigationTiming.notRestoredReasons sẽ trả về một đối tượng có cấu trúc sau, biểu thị trạng thái bị chặn của khung cấp cao nhất:

{
  children: [],
  id: null,
  name: null,
  reasons: [
    {"reason", "unload-listener"}
  ],
  src: null,
  url: "https://www.example.com/page/"
}

Các thuộc tính này như sau:

children
Một mảng các đối tượng đại diện cho trạng thái bị chặn của mọi khung cùng nguồn được nhúng trong khung cấp cao nhất. Mỗi đối tượng đều có cấu trúc giống như đối tượng mẹ. Bằng cách này, bạn có thể biểu thị bất kỳ số lượng cấp độ nào của khung được nhúng bên trong đối tượng một cách đệ quy. Nếu khung hình không có phần tử con, mảng sẽ trống.
id
Một chuỗi biểu thị giá trị thuộc tính id của khung (ví dụ: <iframe id="foo" src="...">). Nếu khung không có id, giá trị sẽ là null. Đối với trang cấp cao nhất, đây là null.
name
Một chuỗi biểu thị giá trị thuộc tính name của khung (ví dụ: <iframe name="bar" src="...">). Nếu khung không có name, giá trị sẽ là một chuỗi trống. Đối với trang cấp cao nhất, đây là null.
reasons
Một mảng gồm các chuỗi, mỗi chuỗi đại diện cho một lý do khiến trang được chuyển hướng bị chặn sử dụng bfcache. Có nhiều lý do khiến việc chặn có thể xảy ra. Hãy xem phần Lý do chặn để biết thêm thông tin chi tiết.
src
Một chuỗi biểu thị đường dẫn đến nguồn của khung (ví dụ: <iframe src="b.html">). Nếu khung không có src, giá trị sẽ là một chuỗi trống. Đối với trang cấp cao nhất, đây là null.
url
Một chuỗi đại diện cho URL của trang/iframe được điều hướng.

Đối với các đối tượng PerformanceNavigationTiming không biểu thị các thao tác điều hướng trong nhật ký, thuộc tính notRestoredReasons sẽ trả về null.

Xin lưu ý rằng notRestoredReasons cũng trả về null khi không có lý do chặn nào. Vì vậy, việc này là null không phải là chỉ báo cho biết bfcache đã được sử dụng hay chưa. Để làm được điều đó, bạn phải sử dụng thuộc tính event.persisted.

Báo cáo việc chặn bfcache trong các khung cùng nguồn gốc

Khi một trang có các khung được nhúng cùng nguồn, giá trị notRestoredReasons được trả về sẽ chứa một đối tượng bên trong thuộc tính children, đại diện cho trạng thái bị chặn của từng khung được nhúng.

Ví dụ:

{
  children: [
    {
      children: [],
      id: "iframe-id",
      name: "iframe-name",
      reasons: [],
      src: "./index.html",
      url: "https://www.example.com/"
    },
    {
      children: [],
      id: "iframe-id2",
      name: "iframe-name2",
      reasons: [
        {"reason": "unload-listener"}
      ],
      src: "./unload-examples.html",
      url: "https://www.example.com/unload-examples.html"
    },
  ],
  id: null,
  name: null,
  reasons: [],
  src: null,
  url:"https://www.example.com"
}

Báo cáo việc chặn bfcache trong các khung hình nhiều nguồn gốc

Khi một trang có các khung nhúng trên nhiều nguồn, chúng tôi sẽ giới hạn lượng thông tin được chia sẻ về các khung đó để tránh rò rỉ thông tin trên nhiều nguồn. Chúng tôi chỉ đưa thông tin mà trang bên ngoài đã biết và liệu cây con nhiều nguồn gốc có chặn bfcache hay không. Chúng tôi không đưa ra bất kỳ lý do chặn nào hoặc thông tin về các cấp thấp hơn của cây con (ngay cả khi một số cấp con có cùng nguồn gốc).

Ví dụ:

{
  children: [
    {
      children: [],
      id: "iframe-id",
      name: "iframe-name",
      reasons: [],
      src: "./index.html",
      url: "https://www.example2.com/"
    }
  ],
  id: null,
  name: null,
  reasons: [
        {"reason": "masked"}
  ],
  src: null,
  url:"https://www.example.com"
}

Đối với tất cả iframe trên nhiều nguồn, chúng tôi sẽ báo cáo null cho giá trị reasons của khung và khung cấp cao nhất sẽ cho thấy lý do là "masked". Xin lưu ý rằng "masked" cũng có thể được dùng vì các lý do cụ thể của tác nhân người dùng, nên không phải lúc nào cũng cho biết có vấn đề trong iframe.

Hãy xem phần Bảo mật và quyền riêng tư trong phần giải thích để biết thêm thông tin chi tiết về các yếu tố cần cân nhắc liên quan đến tính bảo mật và quyền riêng tư.

Lý do chặn

Như đã đề cập trước đó, có nhiều lý do khiến việc chặn có thể xảy ra:

Sau đây là ví dụ về một số lý do phổ biến nhất khiến không thể sử dụng bfcache:

  • unload-listener: trang đăng ký trình xử lý unload, ngăn chặn việc sử dụng bfcache trong một số trình duyệt. Hãy xem bài viết Không dùng sự kiện unload nữa để biết thêm thông tin.
  • response-cache-control-no-store: Trang này sử dụng no-store làm giá trị cache-control.
  • related-active-contents: Trang này được mở từ một trang khác (bằng cách sử dụng "sao chép thẻ") vẫn tham chiếu đến trang này.

Phản hồi

Nhóm Chromium muốn biết ý kiến của bạn về trải nghiệm khi sử dụng API notRestoredReasons của bộ nhớ đệm chuyển tiếp/quay lại (bfcache).

Cho chúng tôi biết về thiết kế API

Có điều gì về API không hoạt động như bạn mong đợi không? Hoặc có phương thức hay thuộc tính nào bị thiếu mà bạn cần triển khai ý tưởng của mình không? Bạn có câu hỏi hoặc bình luận về mô hình bảo mật? Báo cáo vấn đề về quy cách trên kho lưu trữ GitHub tương ứng hoặc thêm ý kiến của bạn vào một vấn đề hiện có.

Báo cáo vấn đề về việc triển khai

Bạn có phát hiện thấy lỗi trong quá trình triển khai Chromium không? Hoặc việc triển khai có khác với quy cách không? Báo cáo lỗi trên công cụ theo dõi lỗi của chúng tôi. Đừng quên cung cấp càng nhiều thông tin chi tiết càng tốt, hướng dẫn đơn giản để tái tạo và chỉ định thành phần là UI > Browser > Navigation > BFCache.

Thể hiện sự ủng hộ đối với API

Bạn có dự định sử dụng API notRestoredReasons bfcache không? Sự ủng hộ công khai của bạn giúp nhóm Chromium ưu tiên các tính năng và cho các nhà cung cấp trình duyệt khác thấy tầm quan trọng của việc hỗ trợ các tính năng này.

Gửi một tweet đến @ChromiumDev bằng thẻ bắt đầu bằng #NotRestoredReasons và cho chúng tôi biết bạn đang sử dụng tính năng này ở đâu và như thế nào.

Đường liên kết hữu ích