Cache invalidation strategies
Thiết lập chính sách cache tối ưu dựa trên phân loại tài nguyên: Vĩnh viễn (immutable) cho các asset tĩnh có chứa content hash và kiểm tra lại liên tục (revalidation) cho HTML hay dữ liệu API.
Bản chất của vô hiệu hóa Cache
Trong phát triển web modern, việc giữ cho các file tĩnh (assets) như JS, CSS, ảnh được lưu trữ ở cache của trình duyệt (hoặc CDN) giúp cải thiện đáng kể tốc độ tải trang ở các lần truy cập tiếp theo.
Tuy nhiên, thách thức lớn nhất là làm thế nào để thông báo cho trình duyệt biết khi nào ứng dụng có phiên bản mới để nó tải file mới thay vì dùng lại bản cũ trong cache. Đây gọi là bài toán **Cache Invalidation**.
Nếu chúng ta sử dụng cơ chế truyền thống như query parameter (ví dụ: style.css?v=1.2), một số proxy trung gian hoặc CDN cũ có thể phớt lờ query string này và tiếp tục phục vụ file cũ. Do đó, tiêu chuẩn vàng hiện nay là **Content Hashing**.
Content Hashing là kỹ thuật băm (hash) nội dung của file (ví dụ bằng thuật toán MD5 hoặc SHA-256) và chèn mã băm đó trực tiếp vào tên file (ví dụ: main.d3a8f9c1.js). Khi nội dung file thay đổi, dù chỉ một dấu phẩy, mã băm sẽ thay đổi hoàn toàn, tạo ra một tên file mới và trình duyệt buộc phải tải lại.
Phân loại chính sách Cache theo tài nguyên
**Tài nguyên tĩnh có băm tên (Hashed Assets)**: Vì tên file thay đổi mỗi khi code thay đổi, chúng ta có thể tự tin cấu hình cache vĩnh viễn với chỉ thị immutable. Trình duyệt sẽ lưu file này mãi mãi mà không bao giờ gửi request kiểm tra lại (revalidate) lên server, ngay cả khi người dùng nhấn F5.
**Tài nguyên động hoặc HTML (HTML / API / JSON)**: File index.html tuyệt đối không được cache vĩnh viễn vì nó chứa các liên kết dẫn đến các file JS/CSS mới nhất. Chúng ta cần sử dụng no-cache (luôn kiểm tra lại với server xem file có thay đổi không trước khi dùng bản cache) hoặc no-store (hoàn toàn không lưu cache, luôn tải mới).
# Cấu hình cho file JS/CSS tĩnh đã băm tên (Cache 1 năm, không revalidate)
Cache-Control: public, max-age=31536000, immutable
# Cấu hình cho index.html và API responses (Luôn hỏi lại server trước khi dùng)
Cache-Control: no-cacheNÊNLuôn tích hợp Content Hashing vào quy trình build (Webpack, Vite, esbuild) cho tất cả các static assets.
KHÔNGĐừng bao giờ đặt max-age dài cho index.html mà thiếu revalidation; người dùng sẽ bị kẹt ở phiên bản cũ và không thể cập nhật ứng dụng.
VÌ SAOChỉ thị 'immutable' ngăn trình duyệt gửi request có điều kiện (conditional request) lên server khi tải lại trang, tiết kiệm tối đa băng thông và giảm tải cho máy chủ.