프론트엔드 기초 다시 쌓기 챌린지 3일차.
오늘은 Chrome DevTools의 Network 탭을 파헤치면서 시작했는데,
캐시 → 스토리지 비교 → CSS 배포 이슈 → CDN → S3 → 이미지 관리 전략까지
꼬리에 꼬리를 물며 엄청나게 많은 걸 배웠다.
어제까지 배운 내용을 한 줄로 요약하면:
.next 폴더에 최적화된 파일이 생긴다오늘은 한 발 더 나아가서, 그 파일들이 실제로 브라우저에 어떻게 도착하는지 관찰해봤다.
Network 탭은 배송 현장을 실시간으로 보는 CCTV 같은 거다.
브라우저가 서버한테 뭘 요청하고 뭘 받는지 1초도 빠짐없이 보여준다.
Windows/Linux: F12
Mac: Cmd + Option + I
→ Network 탭 클릭
→ F5로 새로고침
새로고침하면 아래처럼 파일 목록이 쫙 뜬다.
Name Status Type Size Time
────────────────────────────────────────────────────────────────
example.com 200 document 12.3 KB 45 ms
main-abc123.js 200 script 234 KB 120 ms
styles-xyz.css 200 stylesheet 45 KB 30 ms
logo.png 200 img 8 KB 15 ms
api/users 200 fetch 2 KB 200 ms
브라우저가 다운받은 파일 이름.
잠깐, main-abc123.js 이거 낯익지 않나?
어제 .next/static/chunks/ 폴더에서 봤던 그 해시 붙은 파일!
어제 만든 밀키트(.next 폴더)가 지금 브라우저로 배송된 것이다.
빌드 → 배포 → 브라우저 전체 흐름이 여기서 연결된다.
| 코드 | 의미 |
|---|---|
| 200 | 성공 ✅ |
| 304 | 캐시 사용 (안 바뀌어서 재사용) |
| 404 | 파일 없음 ❌ |
| 500 | 서버 터짐 💥 |
| 401 | 로그인 안 됨 |
document(HTML), script(JS), stylesheet(CSS), img, fetch/xhr(API), font 등.
파일 크기와 로딩 시간.
여기서 어제 배운 "최적화(압축)" 효과가 드러난다.
압축 전: main.js → 2 MB
압축 후: main.js → 234 KB (약 10배 작아짐!)
[1차 방문]
모든 파일 다운로드 → 500 KB → 로딩 2초
[2차 방문 (F5)]
대부분 "304" or "(memory cache)" 표시 → 50 KB → 로딩 0.3초
브라우저가 "어? 이거 아까 받았는데?" 하고 저장해둔 것을 재사용한다.
이게 바로 캐싱(Caching) 이다.
| 표시 | 의미 |
|---|---|
| 304 Not Modified | 서버한테 "바뀌었어요?" 물어봤고, "안 바뀌었어요" 답 받음 → 저장된 거 씀 |
| (memory cache) | 서버한테 묻지도 않고 브라우저 메모리에서 꺼내 씀 (더 빠름) |
| (disk cache) | 하드디스크에서 꺼내 씀 |
어제 배운 해시값(abc123 같은 것) 이 여기서 진가를 발휘한다.
[첫 배포]
파일명: main-abc123.js → 브라우저가 저장
[코드 수정 후 재배포]
파일명: main-def456.js → 해시 바뀜!
브라우저: "어? def456은 처음 봐!" → 새로 다운로드
해시가 바뀌면 브라우저가 새 파일로 인식해서 다시 받는다.
이게 "캐시 무효화"의 핵심 원리였다.
Network 탭을 보다가 궁금한 점이 생겼다.
"브라우저 저장은 캐시라고 하는데, 왜 로컬스토리지·세션스토리지는 캐시라고 안 부르지?"
| 이름 | 저장 주체 | 저장 목적 | 수명 |
|---|---|---|---|
| 캐시 | 브라우저 (자동) | 속도 향상 | 설정된 기간 |
| 로컬스토리지 | 개발자 (수동) | 영구 보관 | 사용자가 지우기 전까지 |
| 세션스토리지 | 개발자 (수동) | 탭 닫을 때까지만 | 탭 닫으면 삭제 |
| 상태관리 (Redux 등) | 개발자 (수동) | 앱 실행 중 공유 | 새로고침하면 삭제 |
| 질문 | 캐시 | 나머지 저장소 |
|---|---|---|
| 누가 저장? | 브라우저가 자동 | 개발자가 직접 |
| 왜 저장? | 속도 | 기능 |
→ 캐시는 "속도를 위한 자동 저장"
→ 나머지는 "기능을 위한 수동 저장"
그래서 부르는 이름이 다르다.
실무에서 자주 만나는 문제. 원인은 캐싱이다.
[시나리오]
사용자가 어제 접속 → styles-abc123.css 브라우저에 저장
개발자가 CSS 수정 후 배포 → 서버에는 styles-def456.css
사용자가 오늘 접속 → 브라우저: "나 abc123 있으니까 그거 쓸래" 😱
브라우저가 오래된 캐시 사용
CDN 캐시 때문 (← 여기서 CDN 등장!)
강한 캐시 정책
Cache-Control: max-age=31536000 (1년!) 같은 설정Ctrl + Shift + R (임시방편)no-cache"CDN 캐시" 얘기가 나왔는데, CDN이 뭔지 제대로 몰랐다. 이번에 확실히 정리했다.
쿠팡 본사 창고가 서울에만 있다면?
[서울 고객] → 1시간 배송 ⚡
[부산 고객] → 8시간 😑
[제주 고객] → 2일 😱
[미국 고객] → 3주 💀
거리 따라 속도 차이가 심하다.
본사 창고 → 전국 로켓배송 센터에 미리 복사
→ 모든 고객이 가까운 센터에서 2시간 이내 받음 ⚡
CDN (Content Delivery Network) = 전세계에 분산된 서버 네트워크
[본사 서버 (서울)]
↓ 파일 미리 복사
[CDN 엣지 서버들]
├── 서울, 도쿄, 싱가포르, 뉴욕, 런던 ... (전세계 수백 곳)
[사용자]
├── 한국 사용자 → 서울 엣지에서 받음 ⚡
├── 일본 사용자 → 도쿄 엣지에서 받음 ⚡
└── 미국 사용자 → 뉴욕 엣지에서 받음 ⚡
S3 (Simple Storage Service) = AWS의 파일 저장소.
이미지, 동영상 같은 파일을 URL로 접근할 수 있게 저장해준다.
https://my-bucket.s3.amazonaws.com/images/profile.jpg
└─ S3 주소 └─ 저장된 파일
S3는 창고일 뿐. 특정 지역에만 있어서 전세계 배송은 느리다.
서울 사용자 → 버지니아 S3 → 500ms 😑
[S3 (저장소)]
↓ 원본 저장
[CloudFront (CDN)]
↓ 전세계 엣지에 복사
[사용자들]
→ 가까운 엣지에서 이미지 받음 ⚡
❌ S3 직접: https://my-bucket.s3.amazonaws.com/profile.jpg
✅ CDN 경유: https://d1234abcd.cloudfront.net/profile.jpg
✅ 커스텀 도메인: https://cdn.mycompany.com/profile.jpg
"그럼 모든 이미지를 S3에 넣으면 되는 건가?"
→ No! 기준이 있다.
"이미지가 바뀌려면 코드 수정이 필요한가?"
✅ 로고, 심볼
✅ UI 아이콘 (돋보기, 화살표, 하트)
✅ 에러 페이지 일러스트
✅ favicon
왜?
✅ 사용자 프로필 이미지 (사용자가 업로드)
✅ 상품 이미지
✅ 게시글 첨부 이미지
✅ 배너 이미지 (관리자가 교체)
✅ 이벤트 페이지 이미지
왜?
| 바꾸는 주체 | 저장 위치 |
|---|---|
| 개발자가 배포하면서 | 코드 |
| 기획자/마케터가 관리자 페이지에서 | S3 + CDN |
| 사용자가 업로드 | S3 + CDN |
<img src="https://my-bucket.s3.amazonaws.com/profile.jpg" />
const CDN_URL = process.env.NEXT_PUBLIC_CDN_URL
<img src={`${CDN_URL}/profile.jpg`} />
# .env.local
NEXT_PUBLIC_CDN_URL=http://localhost:3000/images
# 개발 서버 .env
NEXT_PUBLIC_CDN_URL=https://dev-cdn.mycompany.com
# 실서버 .env
NEXT_PUBLIC_CDN_URL=https://cdn.mycompany.com
어디서 많이 본 패턴이다.
Day 1, Day 2에서 배운 환경변수 .env 관리 그대로다.
같은 코드인데 환경마다 다른 CDN을 쓸 수 있다.
오늘 이해한 것들이 하나의 큰 그림으로 연결됐다.
Day 1: 환경변수 .env는 서버마다 다름
↓
Day 2: 빌드하면 파일에 해시 붙음
↓
Day 3: 브라우저가 캐시해서 속도 향상
↓
Day 3 심화: CDN = 전세계 캐시 서버
→ 전부 "사용자에게 빠르게 전달"이라는 하나의 목적으로 연결됨
단편 지식이 아니라 하나의 큰 그림으로 이해된다는 게 이런 거구나 싶었다.
.env로 환경별 분리Q1 풀면서 "근데 왜 로컬스토리지는 캐시라고 안 부르지?" 라는 의문이 생겼는데,
이 질문 하나가 오늘 학습 전체의 방향을 바꿨다.
Q2 풀면서 "CSS 캐시 문제 해결법" 을 생각하다가 CDN을 만났고,
CDN 설명을 듣다가 "S3랑 CDN 관계" 까지 이어졌고,
거기서 "그럼 이미지는 어디에 둬야 해?" 까지 왔다.
이렇게 호기심 하나가 꼬리에 꼬리를 물고 이어지는 학습이 진짜 재밌다.
단순히 "그런 게 있대" 하고 외운 것과, "이래서 이런 거구나" 하고 이해한 건 완전히 다르다.
앞으로도 질문 많이 하면서 공부해야겠다.
#프론트엔드 #캐시 #CDN #S3 #CloudFront #NetworkTab #ChromeDevTools #2년차개발자 #기초다시쌓기