Giữ cho mọi thứ luôn mới bằng tính năng cũ trong khi xác thực lại

Một công cụ bổ sung giúp bạn cân bằng tính tức thì và tính mới mẻ khi phân phát ứng dụng web.

stale-while-revalidate giúp nhà phát triển cân bằng giữa tính tức thì (tải nội dung đã lưu vào bộ nhớ đệm ngay lập tức) và tính mới mẻ (đảm bảo nội dung cập nhật được lưu vào bộ nhớ đệm sẽ được sử dụng trong tương lai). Nếu bạn duy trì một dịch vụ web hoặc thư viện của bên thứ ba cập nhật theo lịch trình thông thường hoặc các thành phần của bên thứ nhất có xu hướng có thời gian tồn tại ngắn, thì stale-while-revalidate có thể là một bổ sung hữu ích cho các chính sách lưu vào bộ nhớ đệm hiện có.

Tính năng hỗ trợ thiết lập stale-while-revalidate cùng với max-age trong tiêu đề phản hồi Cache-Control có trong Chrome 75Firefox 68.

Các trình duyệt không hỗ trợ stale-while-revalidate sẽ âm thầm bỏ qua giá trị cấu hình đó và sử dụng max-age, như tôi sẽ giải thích ngay sau đây…

Điều này có nghĩa là gì?

Hãy chia stale-while-revalidate thành hai phần: ý tưởng rằng phản hồi được lưu vào bộ nhớ đệm có thể đã lỗi thời và quy trình xác thực lại.

Trước tiên, làm cách nào để trình duyệt biết liệu một phản hồi được lưu vào bộ nhớ đệm có "lỗi thời" hay không? Tiêu đề phản hồi Cache-Control chứa stale-while-revalidate cũng phải chứa max-age và số giây được chỉ định thông qua max-age là yếu tố xác định trạng thái cũ. Mọi phản hồi mới hơn max-age được lưu vào bộ nhớ đệm đều được coi là mới và phản hồi cũ hơn được lưu vào bộ nhớ đệm là cũ.

Nếu phản hồi được lưu vào bộ nhớ đệm cục bộ vẫn mới, thì bạn có thể sử dụng phản hồi đó để thực hiện yêu cầu của trình duyệt. Từ quan điểm của stale-while-revalidate, bạn không cần làm gì trong trường hợp này.

Tuy nhiên, nếu phản hồi được lưu vào bộ nhớ đệm đã cũ, thì một quy trình kiểm tra khác dựa trên thời gian sẽ được thực hiện: thời gian của phản hồi được lưu vào bộ nhớ đệm có nằm trong khoảng thời gian bổ sung do chế độ cài đặt stale-while-revalidate cung cấp không?

Nếu thời gian của một phản hồi cũ nằm trong khoảng thời gian này, thì phản hồi đó sẽ được dùng để thực hiện yêu cầu của trình duyệt. Đồng thời, một yêu cầu "xác thực lại" sẽ được thực hiện đối với mạng theo cách không làm chậm việc sử dụng phản hồi đã lưu vào bộ nhớ đệm. Phản hồi được trả về có thể chứa thông tin giống như phản hồi đã lưu vào bộ nhớ đệm trước đó hoặc có thể khác. Dù bằng cách nào, phản hồi mạng cũng được lưu trữ cục bộ, thay thế mọi nội dung trước đó trong bộ nhớ đệm và đặt lại bộ hẹn giờ "tính mới" được sử dụng trong mọi lần so sánh max-age trong tương lai.

Tuy nhiên, nếu phản hồi cũ trong bộ nhớ đệm đã cũ đến mức nằm ngoài khoảng thời gian stale-while-revalidate, thì phản hồi đó sẽ không thực hiện yêu cầu của trình duyệt. Thay vào đó, trình duyệt sẽ truy xuất phản hồi từ mạng và sử dụng phản hồi đó để thực hiện cả yêu cầu ban đầu và điền phản hồi mới vào bộ nhớ đệm cục bộ.

Ví dụ trực tiếp

Dưới đây là ví dụ đơn giản về một API HTTP để trả về thời gian hiện tại, cụ thể là số phút hiện tại sau giờ.

Trong trường hợp này, máy chủ web sử dụng tiêu đề Cache-Control này trong phản hồi HTTP:

Cache-Control: max-age=1, stale-while-revalidate=59

Chế độ cài đặt này có nghĩa là nếu một yêu cầu về thời gian được lặp lại trong vòng 1 giây tiếp theo, thì giá trị đã lưu vào bộ nhớ đệm trước đó sẽ vẫn mới và được sử dụng nguyên trạng mà không cần xác thực lại.

Nếu một yêu cầu được lặp lại từ 1 đến 60 giây sau đó, thì giá trị được lưu vào bộ nhớ đệm sẽ không còn mới, nhưng sẽ được dùng để thực hiện yêu cầu API. Đồng thời, "ở chế độ nền", một yêu cầu xác thực lại sẽ được thực hiện để điền giá trị mới vào bộ nhớ đệm để sử dụng trong tương lai.

Nếu một yêu cầu được lặp lại sau hơn 60 giây, thì phản hồi cũ sẽ không được sử dụng, đồng thời việc thực hiện yêu cầu của trình duyệt và xác thực lại bộ nhớ đệm sẽ phụ thuộc vào việc nhận được phản hồi từ mạng.

Dưới đây là thông tin chi tiết về 3 trạng thái riêng biệt đó, cùng với khoảng thời gian áp dụng cho từng trạng thái trong ví dụ của chúng ta:

Sơ đồ minh hoạ thông tin trong phần trước.

Có những trường hợp sử dụng phổ biến nào?

Mặc dù ví dụ trên về dịch vụ API "phút sau giờ" là giả định, nhưng ví dụ này minh hoạ trường hợp sử dụng dự kiến – các dịch vụ cung cấp thông tin cần được làm mới, nhưng có thể chấp nhận một mức độ lỗi thời nhất định.

Một số ví dụ ít giả định hơn có thể là API cho tình trạng thời tiết hiện tại hoặc các tin bài hàng đầu được viết trong một giờ qua.

Nhìn chung, mọi phản hồi cập nhật theo một khoảng thời gian đã biết, có khả năng được yêu cầu nhiều lần và ở trạng thái tĩnh trong khoảng thời gian đó đều là ứng cử viên phù hợp để lưu vào bộ nhớ đệm ngắn hạn thông qua max-age. Việc sử dụng stale-while-revalidate ngoài max-age sẽ làm tăng khả năng các yêu cầu trong tương lai có thể được thực hiện từ bộ nhớ đệm bằng nội dung mới hơn mà không bị chặn trên phản hồi mạng.

WebView tương tác với worker dịch vụ như thế nào?

Nếu bạn đã nghe nói về stale-while-revalidate, thì rất có thể đó là trong ngữ cảnh của công thức được sử dụng trong một trình chạy dịch vụ.

Việc sử dụng tính năng cũ-trong-khi-xác thực lại thông qua tiêu đề Cache-Control có một số điểm tương đồng với việc sử dụng tính năng này trong trình làm việc dịch vụ, cũng như nhiều điểm cần cân nhắc tương tự về việc đánh đổi độ mới và thời gian tồn tại tối đa. Tuy nhiên, bạn nên cân nhắc một số yếu tố khi quyết định triển khai phương pháp dựa trên worker dịch vụ hay chỉ dựa vào cấu hình tiêu đề Cache-Control.

Hãy sử dụng phương pháp trình chạy dịch vụ nếu…

  • Bạn đang sử dụng trình chạy dịch vụ trong ứng dụng web.
  • Bạn cần kiểm soát chi tiết nội dung của bộ nhớ đệm và muốn triển khai một chính sách hết hạn như chính sách hết hạn ít được sử dụng gần đây nhất. Mô-đun Hết hạn bộ nhớ đệm của Workbox có thể giúp bạn giải quyết vấn đề này.
  • Bạn muốn được thông báo khi một phản hồi cũ thay đổi ở chế độ nền trong bước xác thực lại. Mô-đun Broadcast Cache Update (Cập nhật bộ nhớ đệm truyền tin) của Workbox có thể giúp bạn thực hiện việc này.
  • Bạn cần hành vi stale-while-revalidate này trong tất cả trình duyệt hiện đại.

Sử dụng phương pháp Cache-Control nếu…

  • Bạn không muốn phải xử lý chi phí triển khai và duy trì worker dịch vụ cho ứng dụng web.
  • Bạn có thể để tính năng quản lý bộ nhớ đệm tự động của trình duyệt ngăn bộ nhớ đệm cục bộ của bạn phát triển quá lớn.
  • Bạn có thể sử dụng một phương pháp hiện không được hỗ trợ trong tất cả trình duyệt hiện đại (kể từ tháng 7 năm 2019; có thể hỗ trợ thêm trong tương lai).

Nếu bạn đang sử dụng worker dịch vụ và cũng đã bật stale-while-revalidate cho một số phản hồi thông qua tiêu đề Cache-Control, thì worker dịch vụ sẽ có "cơ hội đầu tiên" để phản hồi một yêu cầu. Nếu worker dịch vụ quyết định không phản hồi hoặc nếu trong quá trình tạo phản hồi, worker dịch vụ tạo yêu cầu mạng bằng fetch(), thì hành vi được định cấu hình thông qua tiêu đề Cache-Control sẽ có hiệu lực.

Tìm hiểu thêm

Hình ảnh chính của Samuel Zeller.