HTTP Caching
Cơ chế lưu trữ phản hồi HTTP tạm thời tại client hoặc proxy dựa trên các header như Cache-Control, ETag, Expires.
HTTP Caching là gì?
HTTP Caching là cơ chế lưu tạm phản hồi từ máy chủ (như HTML, CSS, JS, ảnh) tại trình duyệt người dùng hoặc các máy chủ trung gian (proxy, CDN), nhằm tránh gửi yêu cầu mới mỗi khi truy cập lại tài nguyên giống nhau. Cơ chế này dựa vào các header HTTP do máy chủ trả về — như Cache-Control, ETag, Expires, Last-Modified — để xác định thời điểm và cách lưu trữ.
Không phải tất cả nội dung đều được cache: trang đăng nhập, kết quả tìm kiếm cá nhân hay dữ liệu nhạy cảm thường bị cấm lưu tạm bằng cách thiết lập Cache-Control: no-store hoặc no-cache. Ngược lại, tài nguyên tĩnh như logo, font hoặc file CSS thường có thời gian cache dài (từ vài giờ đến một năm).
Tại sao quan trọng trong SEO?
Tốc độ tải trang là yếu tố xếp hạng trực tiếp trên Google từ năm 2010 (cho desktop) và 2018 (cho mobile). HTTP Caching giúp giảm thời gian chờ phản hồi (TTFB), giảm số lượng request tới máy chủ, và tăng tỷ lệ thành công khi tải lần hai — từ đó cải thiện chỉ số Core Web Vitals như Largest Contentful Paint (LCP) và Time to Interactive (TTI).
Khi tài nguyên được cache hiệu quả, bot Googlebot cũng tải nhanh hơn, thu thập nhiều trang hơn trong cùng khoảng thời gian crawl budget. Điều này đặc biệt quan trọng với website lớn (trên 50.000 trang). Ngoài ra, trải nghiệm người dùng tốt hơn → giảm tỷ lệ thoát → tín hiệu gián tiếp hỗ trợ thứ hạng.
Cách hoạt động
Khi trình duyệt yêu cầu một tài nguyên (ví dụ: /style.css), nó kiểm tra xem đã có bản cache chưa và còn hạn không. Quy trình gồm hai loại cache chính:
- Cache mạnh (strong caching): Dựa vào
Cache-Control: max-age=31536000hoặcExpires. Nếu còn hạn, trình duyệt dùng ngay bản lưu — KHÔNG gửi request nào tới máy chủ. - Cache yếu (validation caching): Khi hết hạn hoặc có
Cache-Control: must-revalidate, trình duyệt gửi request kèmIf-None-Match(so ETag) hoặcIf-Modified-Since(so Last-Modified). Máy chủ trả về304 Not Modifiednếu nội dung chưa đổi — tiết kiệm băng thông và thời gian.
Hướng dẫn thực hiện
Để bật HTTP Caching đúng cách, cần cấu hình ở cả máy chủ và ứng dụng:
- Xác định nhóm tài nguyên: Phân loại thành "thay đổi ít" (CSS, JS, ảnh) và "thay đổi thường xuyên" (HTML trang chủ, API JSON).
- Thiết lập Cache-Control hợp lý:
- Tài nguyên tĩnh:
Cache-Control: public, max-age=31536000, immutable(nếu dùng tên file có hash nhưmain.a1b2c3.css) - Tài nguyên động nhưng ổn định (ví dụ trang danh mục):
Cache-Control: public, max-age=3600 - Tài nguyên cá nhân:
Cache-Control: no-storehoặcprivate, no-cache
- Tài nguyên tĩnh:
- Bật ETag cho tài nguyên động: Đảm bảo máy chủ sinh ETag dựa trên nội dung (không phải thời gian sửa file) để tránh cache sai khi nội dung giống nhau nhưng timestamp khác.
- Tránh dùng Expires thay thế Cache-Control: Header
Expiresphụ thuộc vào đồng hồ client — dễ sai nếu đồng hồ lệch. Chỉ dùng khi bắt buộc hỗ trợ trình duyệt rất cũ (IE8 trở xuống). - Kiểm tra bằng công cụ: Dùng DevTools (tab Network → cột Size/Transfer),
curl -I https://example.com/style.css, hoặc PageSpeed Insights để xác nhận header được gửi đúng.
Lỗi thường gặp
- Lỗi 1: Cache-Control đặt sai cho trang HTML
→ Triệu chứng: Người dùng không thấy cập nhật nội dung mới sau deploy.
→ Khắc phục: ĐặtCache-Control: public, max-age=1800(30 phút) cho HTML, kết hợp với versioning URL hoặc cache-busting query string cho tài nguyên phụ thuộc. - Lỗi 2: Dùng ETag không nhất quán
→ Triệu chứng: Cùng nội dung trả về ETag khác nhau giữa các server (trong môi trường load balancer), gây cache miss liên tục.
→ Khắc phục: Tắt ETag hoặc cấu hình máy chủ sinh ETag từ hash nội dung (ví dụ: Nginx dùngetag off;+ tùy chỉnh bằng script nếu cần). - Lỗi 3: Cache quá lâu cho tài nguyên thay đổi thường xuyên
→ Triệu chứng: Khách hàng báo lỗi giao diện sau cập nhật CSS/JS.
→ Khắc phục: Áp dụng kỹ thuật cache busting — đổi tên file hoặc thêm query string có hash (ví dụ:app.f3a7e2.js), đồng thời giữmax-agecao cho file mới.
Ví dụ thực tế
Một website tin tức Việt Nam có 2 triệu lượt truy cập/ngày. Trước khi tối ưu cache:
- Trung bình mỗi phiên tải lại 400 KB CSS/JS từ server — tốn 120 ms/request do mạng và xử lý backend.
- Tỷ lệ cache hit ở CDN chỉ đạt 45%.
Sau khi áp dụng:
- File CSS/JS được đặt
Cache-Control: public, max-age=31536000, immutablevà đổi tên theo hash. - HTML trang bài viết dùng
Cache-Control: public, max-age=600(10 phút), vì nội dung cập nhật nhanh. - API lấy dữ liệu comment dùng
Cache-Control: no-cache, must-revalidate+ ETag.
Kết quả sau 2 tuần:
- Tỷ lệ cache hit ở CDN tăng lên 89%.
- Thời gian tải trung bình giảm 42% trên mobile (từ 3.8s → 2.2s).
- Traffic organic tăng 11% nhờ cải thiện chỉ số LCP và giảm thoát.
Câu hỏi thường gặp
Cache-Control và Expires khác nhau thế nào?
Cache-Control là header hiện đại, ưu tiên cao hơn và hỗ trợ nhiều directive (như immutable, stale-while-revalidate). Expires chỉ là thời điểm tuyệt đối tính theo GMT — dễ sai nếu đồng hồ client lệch. Theo RFC 9111, nếu cả hai cùng tồn tại, Cache-Control được ưu tiên.
ETag có bắt buộc phải dùng không?
Không bắt buộc. Với tài nguyên tĩnh có max-age dài và tên file thay đổi theo nội dung (hash-based), ETag gần như thừa. Nhưng với tài nguyên động (HTML, JSON API), ETag giúp giảm tải server khi nội dung không thay đổi — nên dùng nếu máy chủ hỗ trợ đúng cách.
Cache trên CDN có khác với cache trình duyệt không?
Có. Cache trình duyệt là cấp cuối cùng, thuộc về người dùng. Cache CDN là cấp trung gian, chia sẻ giữa nhiều người dùng. CDN tuân theo cùng quy tắc HTTP nhưng có thể có thêm chính sách riêng (ví dụ: Cloudflare tự động cache tài nguyên tĩnh dù máy chủ không gửi Cache-Control). Cách tốt nhất là chủ động kiểm soát qua header — không phụ thuộc vào hành vi mặc định của CDN.
| Header | Vai trò | Giá trị mẫu | Ghi chú |
|---|---|---|---|
Cache-Control |
Điều khiển hành vi cache chi tiết | public, max-age=3600, stale-while-revalidate=86400 |
Ưu tiên cao nhất; bắt buộc dùng cho mọi tài nguyên |
ETag |
Định danh duy nhất cho phiên bản nội dung | "abc123" |
Nên dùng cho tài nguyên động; tránh dùng nếu không kiểm soát được tính nhất quán |
Expires |
Thời điểm hết hạn cache (GMT) | Wed, 21 Oct 2025 07:28:00 GMT |
Chỉ dùng khi cần hỗ trợ IE8–; không nên dùng song song với max-age |
Last-Modified |
Thời điểm sửa cuối cùng của tài nguyên | Mon, 15 Apr 2024 10:30:00 GMT |
Ít chính xác hơn ETag nếu nội dung không đổi nhưng file bị ghi lại |