Files
2nd/10_Wiki/Topics/Coding/Web_HTTP_Cache_Headers.md
T
2026-05-09 21:08:02 +09:00

3.5 KiB

id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
id title category status source_trust_level verification_status created_at updated_at tags tech_stack applied_in aliases
web-http-cache-headers HTTP Cache 헤더 실전 Coding draft B conceptual 2026-05-09 2026-05-09
web
http
caching
performance
vibe-coding
language applicable_to
Any backend / CDN
Web
API
Cache-Control
ETag
immutable
stale-while-revalidate

HTTP Cache 헤더 실전

캐시 정책 4종 = (1) 정적 자산은 immutable + long max-age, (2) HTML 은 short max-age + revalidate, (3) API GET 은 ETag + private, (4) 절대 캐시 금지는 no-store. 한 응답에 여러 정책 섞으면 사고.

📖 핵심 개념

  • Cache-Control: max-age=N — N초 동안 fresh
  • Cache-Control: s-maxage=N — CDN 만 (브라우저는 무시)
  • Cache-Control: immutable — 만료 전 절대 revalidate 안 함
  • Cache-Control: no-store — 어디에도 저장 X (보안 응답)
  • Cache-Control: no-cache — 저장은 OK, 매번 revalidate 필요
  • ETag + If-None-Match — 변경 안 됐으면 304
  • stale-while-revalidate=N — stale 응답 즉시 + 백그라운드 재검증

💻 코드 패턴

1. 정적 자산 (해시 파일명)

GET /assets/app.a1b2c3d4.js
Cache-Control: public, max-age=31536000, immutable

파일명에 hash 가 있으면 영원히 캐시. 새 deploy = 새 hash = 자동 cache miss.

2. HTML

GET /index.html
Cache-Control: public, max-age=0, must-revalidate
ETag: "v123"

매 요청 revalidate. 변경 없으면 304. 새 빌드 즉시 노출.

3. API GET (사용자별)

GET /api/me
Cache-Control: private, max-age=60
ETag: "user-1-v5"

private = CDN 캐시 금지. 사용자 브라우저만.

GET /api/posts
Cache-Control: public, max-age=60, stale-while-revalidate=300

60초까지 fresh. 60~360초 사이 = stale 즉시 반환 + 백그라운드 fetch. 사용자는 latency 0.

5. 절대 캐시 금지

GET /api/transfer
Cache-Control: no-store

민감 응답 (잔액, 비밀, 인증 토큰). 프록시도 저장 안 함.

🤔 의사결정 기준

자원 정책
JS/CSS (hashed) public, max-age=1y, immutable
이미지 (hashed) public, max-age=1y, immutable
index.html public, max-age=0, must-revalidate
공개 API (popular) public, max-age=60, stale-while-revalidate=300
사용자별 API private, max-age=60 + ETag
결제 / 잔액 / 토큰 no-store
사용자 입력 후 즉시 일관성 no-cache 또는 짧은 max-age

안티패턴

  • HTML 에 max-age: 31536000: 새 deploy 가 사용자에게 영원히 안 보임.
  • API 에 public + 사용자별 데이터: CDN 이 다른 사용자에게 줘 보안 사고. private 명시.
  • ETag 없이 max-age 만: 만료 후 재다운로드. ETag 있으면 304 로 bandwidth 절약.
  • no-cachemax-age 의미 혼동: no-cache = 매번 revalidate, no-store = 저장 금지.
  • CDN 과 브라우저 정책 따로 못 둠: s-maxage=3600, max-age=60 → CDN 1시간, 브라우저 1분.
  • POST 응답에 캐시 헤더: 일부 프록시가 저장. 의도면 OK 지만 실수면 위험.
  • Vary 헤더 잊음: Accept-Encoding, Authorization 같은 헤더로 분리 캐시 안 하면 다른 사용자에게 잘못 응답.

🤖 LLM 활용 힌트

  • 정적 자산 vs HTML vs API 구분 명시.
  • 사용자별 응답이면 private + Vary 검토.

🔗 관련 문서