docs(10_Wiki): 위키 전체 재구성 — Topic_* 폴더를 4개 카테고리로 통합 + 대규모 중복 제거
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
---
|
||||
id: web-http-cache-headers
|
||||
title: HTTP Cache 헤더 실전
|
||||
category: Coding
|
||||
status: draft
|
||||
source_trust_level: B
|
||||
verification_status: conceptual
|
||||
created_at: 2026-05-09
|
||||
updated_at: 2026-05-09
|
||||
tags: [web, http, caching, performance, vibe-coding]
|
||||
tech_stack: { language: "Any backend / CDN", applicable_to: ["Web", "API"] }
|
||||
applied_in: []
|
||||
aliases: [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. 정적 자산 (해시 파일명)
|
||||
```http
|
||||
GET /assets/app.a1b2c3d4.js
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
```
|
||||
파일명에 hash 가 있으면 영원히 캐시. 새 deploy = 새 hash = 자동 cache miss.
|
||||
|
||||
### 2. HTML
|
||||
```http
|
||||
GET /index.html
|
||||
Cache-Control: public, max-age=0, must-revalidate
|
||||
ETag: "v123"
|
||||
```
|
||||
매 요청 revalidate. 변경 없으면 304. 새 빌드 즉시 노출.
|
||||
|
||||
### 3. API GET (사용자별)
|
||||
```http
|
||||
GET /api/me
|
||||
Cache-Control: private, max-age=60
|
||||
ETag: "user-1-v5"
|
||||
```
|
||||
private = CDN 캐시 금지. 사용자 브라우저만.
|
||||
|
||||
### 4. stale-while-revalidate (popular)
|
||||
```http
|
||||
GET /api/posts
|
||||
Cache-Control: public, max-age=60, stale-while-revalidate=300
|
||||
```
|
||||
60초까지 fresh. 60~360초 사이 = stale 즉시 반환 + 백그라운드 fetch. 사용자는 latency 0.
|
||||
|
||||
### 5. 절대 캐시 금지
|
||||
```http
|
||||
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-cache` 와 `max-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 검토.
|
||||
|
||||
## 🔗 관련 문서
|
||||
- [[Web_CORS_Practical_Guide]]
|
||||
- [[Optimistic_Concurrency_Control]]
|
||||
Reference in New Issue
Block a user