Bốn chiến lược chính, khác nhau ở thứ tự hỏi cache và mạng:
- Cache-first: có trong cache thì trả luôn, không có mới ra mạng. Nhanh nhất nhưng dễ phục vụ nội dung cũ.
- Network-first: ưu tiên mạng, hỏng mạng mới lấy cache. Luôn mới nhưng chậm hơn và phụ thuộc mạng.
- Stale-while-revalidate: trả cache ngay, đồng thời gọi mạng để cập nhật cho lần sau. Cân bằng tốt nhất cho nội dung đổi vừa phải.
- Network-only / Cache-only: dùng cho request không được cache (thanh toán) hoặc asset precache thuần.
Ánh xạ theo loại tài nguyên:
- Asset có hash trong tên (app.3f9a1.js, font, ảnh) → cache-first, vì URL đổi mỗi lần build nên không bao giờ cũ.
- HTML / document → network-first (hoặc SWR kèm thông báo cập nhật). Cache-first cho HTML là lỗi kinh điển: người dùng bị khóa ở bản cũ dù đã deploy, vì HTML cũ trỏ tới chunk JS đã bị xóa → trang trắng.
- API dữ liệu → SWR cho danh sách đọc nhiều; network-only cho thao tác ghi và dữ liệu nhạy cảm.
js
// stale-while-revalidate
self.addEventListener('fetch', (e) => {
e.respondWith((async () => {
const cache = await caches.open('v3')
const cached = await cache.match(e.request)
const fresh = fetch(e.request).then((res) => {
cache.put(e.request, res.clone())
return res
})
return cached || fresh
})())
})Hai điểm bắt buộc nhớ: Response chỉ đọc được một lần nên phải clone() trước khi put, và phải xóa cache phiên bản cũ trong activate nếu không quota sẽ đầy dần.