Technical SEO

Cache-Control Headers

Header HTTP chỉ định cách trình duyệt và CDN lưu trữ và tái sử dụng tài nguyên, ảnh hưởng đến tốc độ tải và crawl efficiency.

2 lượt xem Cập nhật: 29/05/2026

Cache-Control Headers là gì?

Cache-Control Headers là các chỉ thị HTTP được gửi từ máy chủ về trình duyệt hoặc proxy (như CDN) để điều khiển cách tài nguyên (HTML, CSS, JS, ảnh…) được lưu tạm (cache), thời gian lưu, và điều kiện tái sử dụng. Đây không phải là một header duy nhất, mà là một tập hợp các giá trị trong header Cache-Control, ví dụ: max-age=3600, public, no-store.

Khác với các header như Expires (dựa trên thời gian tuyệt đối), Cache-Control dùng thời gian tương đối tính từ lúc phản hồi được gửi — nên chính xác hơn và được ưu tiên hơn theo tiêu chuẩn HTTP/1.1.

Tại sao quan trọng trong SEO?

Cache-Control ảnh hưởng trực tiếp đến hai yếu tố then chốt của Technical SEO:

  • Tốc độ tải trang: Khi tài nguyên được cache hiệu quả, trình duyệt không cần tải lại từ máy chủ → giảm số lần yêu cầu, giảm thời gian render → cải thiện Core Web Vitals (đặc biệt LCP và CLS).
  • Hiệu quả thu thập (crawl efficiency): Googlebot tuân thủ các chỉ thị cache. Nếu tài nguyên tĩnh (ví dụ: logo.png) có Cache-Control: public, max-age=31536000, bot sẽ không kiểm tra lại hàng năm → giải phóng băng thông crawl cho các URL quan trọng hơn như trang sản phẩm hoặc bài viết mới.
  • Bảo mật và kiểm soát nội dung: Các chỉ thị như no-cache hay private giúp ngăn cache nhạy cảm (trang đăng nhập, dữ liệu cá nhân) trên thiết bị người dùng hoặc mạng chung.

Ngược lại, cấu hình sai có thể khiến trang hiển thị nội dung lỗi thời, làm chậm trải nghiệm người dùng, hoặc gây ra hiện tượng “trang cũ vẫn xuất hiện trên Google” dù đã cập nhật.

Cách hoạt động

Khi trình duyệt yêu cầu một tài nguyên, máy chủ trả về response kèm header Cache-Control. Trình duyệt hoặc CDN đọc chỉ thị này và quyết định:

  1. Có lưu vào bộ nhớ đệm hay không?
  2. Lưu bao lâu? (theo max-age hoặc s-maxage)
  3. Có được chia sẻ giữa nhiều người dùng không? (public vs private)
  4. Có cần xác thực lại với máy chủ trước khi dùng cache không? (no-cache ≠ “không lưu”, mà là “phải kiểm tra lại”)

Lưu ý: Nếu cả Cache-ControlExpires đều tồn tại, Cache-Control luôn được ưu tiên. Các chỉ thị cũng có thể kết hợp, ví dụ: Cache-Control: public, max-age=86400, immutable.

Hướng dẫn thực hiện

Thiết lập Cache-Control đúng đòi hỏi phân loại tài nguyên và mục đích sử dụng. Dưới đây là hướng dẫn từng bước:

  1. Phân nhóm tài nguyên:
    • Tài nguyên tĩnh không đổi (CSS, JS, ảnh): đặt max-age cao (ví dụ 1 năm = 31536000 giây)
    • Tài nguyên thay đổi thường xuyên (trang HTML, RSS feed): dùng max-age=0 hoặc no-cache
    • Tài nguyên nhạy cảm (trang thanh toán, hồ sơ cá nhân): dùng no-store
  2. Cấu hình trên máy chủ:
    • Apache: Dùng .htaccess hoặc httpd.conf với mod_expires hoặc mod_headers. Ví dụ:
      Header set Cache-Control "public, max-age=31536000, immutable" "expr=%{REQUEST_FILENAME} =~ m/\.(css|js|jpg|jpeg|png|gif|webp|woff2)$/"
    • Nginx: Thêm vào khối location:
      location ~* \.(css|js|png|jpg|jpeg|gif|webp|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; }
    • Node.js (Express): Dùng middleware res.set() hoặc express.static() với tùy chọn maxAge.
  3. Kiểm tra kết quả: Dùng DevTools (tab Network → chọn file → xem phần Headers → Response Headers) hoặc công cụ dòng lệnh: curl -I https://example.com/style.css.

Lỗi thường gặp

  • Lỗi 1: Đặt Cache-Control: no-cache cho toàn bộ trang HTML

    → Dẫn đến mỗi lần tải đều gọi lại máy chủ, làm chậm trang và tăng tải server. Cách khắc phục: Chỉ áp dụng no-cache hoặc max-age=0 cho trang động; dùng stale-while-revalidate nếu muốn cân bằng giữa tốc độ và độ tươi.

  • Lỗi 2: Không dùng immutable cho tài nguyên có hash tên file (ví dụ main.a1b2c3.js)

    → Trình duyệt vẫn kiểm tra lại (revalidation) dù file không bao giờ thay đổi. Cách khắc phục: Thêm immutable vào header khi tên file chứa hash — giúp bỏ qua revalidation hoàn toàn.

  • Lỗi 3: Đặt public cho trang cá nhân hoặc admin

    → CDN hoặc proxy có thể lưu và phát lại nội dung riêng tư. Cách khắc phục: Dùng private hoặc no-store cho nội dung người dùng.

Ví dụ thực tế

Dưới đây là bảng minh hoạ cách cấu hình Cache-Control theo loại tài nguyên phổ biến:

Loại tài nguyên Ví dụ Cache-Control đề xuất Ghi chú
Tài nguyên tĩnh có hash app.7f3a2d.js, logo.f9e8b1.png public, max-age=31536000, immutable Không bao giờ thay đổi → cache tối đa + bỏ qua kiểm tra
Tài nguyên tĩnh không có hash style.css, script.js public, max-age=604800 (7 ngày) Cần cân nhắc khả năng cập nhật thủ công
Trang HTML động /tin-tuc/, /san-pham/ no-cache hoặc max-age=0, must-revalidate Đảm bảo bot và người dùng luôn thấy phiên bản mới nhất
Trang nhạy cảm /tai-khoan/, /dang-nhap/ no-store Không lưu bất kỳ đâu — an toàn tuyệt đối

Câu hỏi thường gặp

Cache-Control có ảnh hưởng đến xếp hạng Google không?

Có gián tiếp. Google không dùng Cache-Control làm tín hiệu xếp hạng trực tiếp, nhưng nó tác động mạnh đến tốc độ tải và trải nghiệm người dùng — hai yếu tố nằm trong Core Web Vitals và được dùng làm tín hiệu xếp hạng trên mobile. Trang chậm do cache sai có thể bị giảm thứ hạng trong tìm kiếm di động.

max-age=0 và no-cache khác nhau thế nào?

max-age=0 nghĩa là tài nguyên hết hạn ngay khi nhận — trình duyệt phải gửi yêu cầu conditional GET (với If-None-Match hoặc If-Modified-Since) để kiểm tra. no-cache cũng yêu cầu xác thực lại trước khi dùng cache, nhưng không bắt buộc phải hết hạn — nó nhấn mạnh vào việc kiểm tra tính mới nhất, không phải thời gian sống.

Có nên dùng s-maxage cho tất cả tài nguyên?

s-maxage chỉ áp dụng cho shared cache (CDN, proxy), không ảnh hưởng đến trình duyệt. Bạn chỉ nên dùng khi muốn thiết lập thời gian cache riêng cho CDN khác với trình duyệt — ví dụ: trình duyệt cache 1 giờ (max-age=3600), còn CDN cache 24 giờ (s-maxage=86400). Tùy trường hợp, không bắt buộc với mọi website.