[Day 3] 브라우저가 실제로 받는 파일은? (Network 탭부터 CDN까지)

짱효·2026년 4월 23일

프론트엔드 기초 다시 쌓기 챌린지 3일차.
오늘은 Chrome DevTools의 Network 탭을 파헤치면서 시작했는데,
캐시 → 스토리지 비교 → CSS 배포 이슈 → CDN → S3 → 이미지 관리 전략까지
꼬리에 꼬리를 물며 엄청나게 많은 걸 배웠다.


🕵️ Network 탭 = 브라우저의 CCTV

어제까지 배운 내용을 한 줄로 요약하면:

  • Day 1: 코드를 빌드해서 배포한다
  • Day 2: 빌드하면 .next 폴더에 최적화된 파일이 생긴다

오늘은 한 발 더 나아가서, 그 파일들이 실제로 브라우저에 어떻게 도착하는지 관찰해봤다.

Network 탭은 배송 현장을 실시간으로 보는 CCTV 같은 거다.
브라우저가 서버한테 뭘 요청하고 뭘 받는지 1초도 빠짐없이 보여준다.

Network 탭 여는 법

Windows/Linux: F12
Mac:          Cmd + Option + I

→ Network 탭 클릭
→ F5로 새로고침

📊 Network 탭의 각 컬럼 읽는 법

새로고침하면 아래처럼 파일 목록이 쫙 뜬다.

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

1️⃣ Name (파일 이름)

브라우저가 다운받은 파일 이름.

잠깐, main-abc123.js 이거 낯익지 않나?

어제 .next/static/chunks/ 폴더에서 봤던 그 해시 붙은 파일!
어제 만든 밀키트(.next 폴더)가 지금 브라우저로 배송된 것이다.

빌드 → 배포 → 브라우저 전체 흐름이 여기서 연결된다.

2️⃣ Status (응답 코드)

코드의미
200성공 ✅
304캐시 사용 (안 바뀌어서 재사용)
404파일 없음 ❌
500서버 터짐 💥
401로그인 안 됨

3️⃣ Type (파일 종류)

document(HTML), script(JS), stylesheet(CSS), img, fetch/xhr(API), font 등.

4️⃣ Size / Time

파일 크기와 로딩 시간.
여기서 어제 배운 "최적화(압축)" 효과가 드러난다.

압축 전: main.js → 2 MB
압축 후: main.js → 234 KB (약 10배 작아짐!)

💾 캐싱: 같은 파일을 두 번 받지 않는 마법

첫 방문 vs 두 번째 방문

[1차 방문]
모든 파일 다운로드 → 500 KB → 로딩 2초

[2차 방문 (F5)]
대부분 "304" or "(memory cache)" 표시 → 50 KB → 로딩 0.3초

왜 이런 일이?

브라우저가 "어? 이거 아까 받았는데?" 하고 저장해둔 것을 재사용한다.
이게 바로 캐싱(Caching) 이다.

304 vs (memory cache) 차이

표시의미
304 Not Modified서버한테 "바뀌었어요?" 물어봤고, "안 바뀌었어요" 답 받음 → 저장된 거 씀
(memory cache)서버한테 묻지도 않고 브라우저 메모리에서 꺼내 씀 (더 빠름)
(disk cache)하드디스크에서 꺼내 씀

해시의 정체 드디어 밝혀짐

어제 배운 해시값(abc123 같은 것) 이 여기서 진가를 발휘한다.

[첫 배포]
파일명: main-abc123.js → 브라우저가 저장

[코드 수정 후 재배포]
파일명: main-def456.js → 해시 바뀜!

브라우저: "어? def456은 처음 봐!" → 새로 다운로드

해시가 바뀌면 브라우저가 새 파일로 인식해서 다시 받는다.
이게 "캐시 무효화"의 핵심 원리였다.


🤔 캐시 vs 로컬스토리지 vs 세션스토리지 vs 상태관리

Network 탭을 보다가 궁금한 점이 생겼다.
"브라우저 저장은 캐시라고 하는데, 왜 로컬스토리지·세션스토리지는 캐시라고 안 부르지?"

한 눈에 비교

이름저장 주체저장 목적수명
캐시브라우저 (자동)속도 향상설정된 기간
로컬스토리지개발자 (수동)영구 보관사용자가 지우기 전까지
세션스토리지개발자 (수동)탭 닫을 때까지만탭 닫으면 삭제
상태관리 (Redux 등)개발자 (수동)앱 실행 중 공유새로고침하면 삭제

비유로 이해하기

  • 캐시 = 편의점 진열대 — 자주 팔리는 물건을 자동으로 꺼내둠
  • 로컬스토리지 = 집 장롱 — 내가 직접 넣어서 영구 보관 (토큰, 다크모드)
  • 세션스토리지 = 출근 가방 — 오늘 하루만 들고 다님 (결제 진행 중 데이터)
  • 상태관리 = 사무실 화이트보드 — 여러 컴포넌트가 공유 (장바구니, 로그인 여부)

핵심 차이

질문캐시나머지 저장소
누가 저장?브라우저가 자동개발자가 직접
왜 저장?속도기능

→ 캐시는 "속도를 위한 자동 저장"
→ 나머지는 "기능을 위한 수동 저장"

그래서 부르는 이름이 다르다.


🚨 "CSS 수정했는데 화면이 안 바뀌어요" 이슈

실무에서 자주 만나는 문제. 원인은 캐싱이다.

왜 이런 일이?

[시나리오]
사용자가 어제 접속 → styles-abc123.css 브라우저에 저장
개발자가 CSS 수정 후 배포 → 서버에는 styles-def456.css
사용자가 오늘 접속 → 브라우저: "나 abc123 있으니까 그거 쓸래" 😱

원인 3가지

  1. 브라우저가 오래된 캐시 사용

    • HTML이 캐시되면 옛날 경로 계속 참조
  2. CDN 캐시 때문 (← 여기서 CDN 등장!)

    • CDN이라는 중간 서버에 옛날 파일이 저장되어 있음
  3. 강한 캐시 정책

    • Cache-Control: max-age=31536000 (1년!) 같은 설정

해결 방법

  1. 강력 새로고침: Ctrl + Shift + R (임시방편)
  2. 해시 기반 파일명 제대로 동작 확인: 빌드하면 자동으로 해시 바뀜
  3. HTML은 캐시 안 되게 설정: no-cache
  4. CDN 캐시 초기화(Purge): CloudFront Invalidation 등

🌐 CDN이 도대체 뭐야?

"CDN 캐시" 얘기가 나왔는데, CDN이 뭔지 제대로 몰랐다. 이번에 확실히 정리했다.

문제 상황으로 이해하기

쿠팡 본사 창고가 서울에만 있다면?

[서울 고객] → 1시간 배송 ⚡
[부산 고객] → 8시간 😑
[제주 고객] → 2일 😱
[미국 고객] → 3주 💀

거리 따라 속도 차이가 심하다.

해결책: 전국에 로켓배송 센터

본사 창고 → 전국 로켓배송 센터에 미리 복사
→ 모든 고객이 가까운 센터에서 2시간 이내 받음 ⚡

CDN = 인터넷의 로켓배송 센터

CDN (Content Delivery Network) = 전세계에 분산된 서버 네트워크

[본사 서버 (서울)]
    ↓ 파일 미리 복사

[CDN 엣지 서버들]
├── 서울, 도쿄, 싱가포르, 뉴욕, 런던 ... (전세계 수백 곳)

[사용자]
├── 한국 사용자 → 서울 엣지에서 받음 ⚡
├── 일본 사용자 → 도쿄 엣지에서 받음 ⚡
└── 미국 사용자 → 뉴욕 엣지에서 받음 ⚡

CDN의 3가지 효과

  1. 속도 향상 ⚡ — 사용자 근처 서버에서 받으니 빠름 (10배 차이)
  2. 본사 서버 부하 감소 💪 — 트래픽 분산
  3. 비용 절감 💰 — 서버 비용 줄어듦

유명한 CDN 서비스

  • CloudFront (AWS)
  • Cloudflare
  • Akamai
  • Fastly

📦 S3와 CDN의 관계

S3가 뭐야?

S3 (Simple Storage Service) = AWS의 파일 저장소.
이미지, 동영상 같은 파일을 URL로 접근할 수 있게 저장해준다.

https://my-bucket.s3.amazonaws.com/images/profile.jpg
         └─ S3 주소                  └─ 저장된 파일

S3 단독의 한계

S3는 창고일 뿐. 특정 지역에만 있어서 전세계 배송은 느리다.

서울 사용자 → 버지니아 S3 → 500ms 😑

S3 + CloudFront = 황금 조합

[S3 (저장소)]
    ↓ 원본 저장

[CloudFront (CDN)]
    ↓ 전세계 엣지에 복사

[사용자들]
→ 가까운 엣지에서 이미지 받음 ⚡

URL로 구분하기

❌ S3 직접:     https://my-bucket.s3.amazonaws.com/profile.jpg
✅ CDN 경유:    https://d1234abcd.cloudfront.net/profile.jpg
✅ 커스텀 도메인: https://cdn.mycompany.com/profile.jpg

🖼️ 이미지를 어디에 둘지 판단 기준

"그럼 모든 이미지를 S3에 넣으면 되는 건가?"
→ No! 기준이 있다.

핵심 질문

"이미지가 바뀌려면 코드 수정이 필요한가?"

  • ✅ YES → 코드에 포함
  • ❌ NO (사용자/관리자가 업로드) → S3 + CDN

📁 코드에 포함할 것

✅ 로고, 심볼
✅ UI 아이콘 (돋보기, 화살표, 하트)
✅ 에러 페이지 일러스트
✅ favicon

왜?

  • 번들링 시 합쳐져서 한 번에 로딩
  • 빌드 시 해시 자동 생성 → 캐시 무효화 자동
  • 배포 프로세스에 포함됨

📦 S3 + CDN에 넣을 것

✅ 사용자 프로필 이미지 (사용자가 업로드)
✅ 상품 이미지
✅ 게시글 첨부 이미지
✅ 배너 이미지 (관리자가 교체)
✅ 이벤트 페이지 이미지

왜?

  • 깃에 넣으면 레포 용량 폭발
  • 배포 없이 이미지만 교체 가능
  • 용량 제한 없음

바꾸는 주체별 정리

바꾸는 주체저장 위치
개발자가 배포하면서코드
기획자/마케터가 관리자 페이지에서S3 + CDN
사용자가 업로드S3 + CDN

💡 실무 꿀팁: CDN URL은 환경변수로

👎 이렇게 하지 마세요

<img src="https://my-bucket.s3.amazonaws.com/profile.jpg" />
  • S3 주소 직접 노출 → 속도 느림
  • 나중에 CDN으로 바꾸면 모든 코드 수정 필요

👍 이렇게 하세요

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 = 전세계 캐시 서버

→ 전부 "사용자에게 빠르게 전달"이라는 하나의 목적으로 연결됨

단편 지식이 아니라 하나의 큰 그림으로 이해된다는 게 이런 거구나 싶었다.


🎯 오늘 배운 것 최종 정리

1. Network 탭 읽는 법

  • Name, Status, Type, Size, Time 각 컬럼 의미
  • 200, 304, (memory cache) 차이

2. 캐싱의 원리

  • 브라우저가 파일을 저장해뒀다가 재사용 → 속도 향상
  • 해시값이 바뀌면 새 파일로 인식해서 다시 받음

3. 캐시 vs 스토리지 차이

  • 캐시: 브라우저 자동, 속도 목적
  • 로컬/세션스토리지, 상태관리: 개발자 수동, 기능 목적

4. CSS 수정 후 안 바뀌는 이슈

  • 원인: 브라우저 캐시, CDN 캐시, HTML 캐시 정책
  • 해결: 강력 새로고침, 해시 기반 파일명, CDN Invalidation

5. CDN의 정체

  • 전세계에 분산된 서버 네트워크
  • 사용자 근처 엣지 서버에서 파일 제공 → 속도 향상
  • 대표 서비스: CloudFront, Cloudflare

6. S3 + CDN 조합

  • S3: 저장소
  • CloudFront: CDN
  • 둘을 합쳐서 전세계 빠른 이미지 전송

7. 이미지 저장 위치 판단 기준

  • "코드 수정 없이 바뀌나?"
  • 개발자만 바꿈 → 코드
  • 사용자/관리자가 바꿈 → S3 + CDN

8. CDN URL은 환경변수로 관리

  • 하드코딩 금지
  • .env로 환경별 분리

💭 회고

Q1 풀면서 "근데 왜 로컬스토리지는 캐시라고 안 부르지?" 라는 의문이 생겼는데,
이 질문 하나가 오늘 학습 전체의 방향을 바꿨다.

Q2 풀면서 "CSS 캐시 문제 해결법" 을 생각하다가 CDN을 만났고,
CDN 설명을 듣다가 "S3랑 CDN 관계" 까지 이어졌고,
거기서 "그럼 이미지는 어디에 둬야 해?" 까지 왔다.

이렇게 호기심 하나가 꼬리에 꼬리를 물고 이어지는 학습이 진짜 재밌다.
단순히 "그런 게 있대" 하고 외운 것과, "이래서 이런 거구나" 하고 이해한 건 완전히 다르다.

앞으로도 질문 많이 하면서 공부해야겠다.


📚 다음 학습 예고

  • Day 4: 왜 번들링이 필요한가? (webpack, esbuild 개념)
  • 내 프로젝트 번들 사이즈 확인해보기
  • Tree Shaking 맛보기

#프론트엔드 #캐시 #CDN #S3 #CloudFront #NetworkTab #ChromeDevTools #2년차개발자 #기초다시쌓기

profile
✨🌏확장해 나가는 프론트엔드 개발자입니다✏️

0개의 댓글