브라우저 캐시 vs 서버 캐시 vs CDN: 웹 캐싱 3종 세트 차이와 적용 순서

사이트가 “처음엔 괜찮은데 왜 계속 느리지?” 싶은 순간이 있습니다. 특히 워드프레스는 플러그인, 테마, 이미지가 쌓일수록 캐싱 전략이 더 중요해져요.

독자가 흔히 겪는 상황 3가지:

  • 새 글을 올렸는데 내 PC에서는 바뀌었고 방문자 화면은 예전 CSS가 남아 레이아웃이 깨짐
  • 트래픽이 조금만 늘어도 TTFB(첫 바이트 시간)가 늘고 서버가 버벅임
  • 해외/모바일 유입이 많아지니 이미지 로딩이 느리고 페이지가 묵직해짐

이 글을 읽고 얻는 결과 3가지:

  • 브라우저 캐시 / 서버 캐시 / CDN이 각각 무엇을, 어디서, 왜 캐시하는지 명확히 구분
  • 워드프레스 환경에서 충돌(로그인/장바구니/관리자 화면 깨짐) 없이 적용하는 기본 원칙 습득
  • 적용 후 **검증 방법(헤더 확인, 캐시 히트 확인, 업데이트 반영 방법)**까지 한 번에 정리

핵심 개념 정리

캐시는 “같은 결과물을 다시 만들지 않고 재사용”하는 기술입니다. 저는 이렇게 비유합니다.

  • 브라우저 캐시 = 내 집 책장: 한 번 받은 CSS/JS/이미지를 내 PC(브라우저)에 저장해 두고 재방문 때 재사용
  • 서버 캐시 = 도서관 내부 창고: PHP 실행/DB 조회로 만든 결과(HTML 등)를 서버가 저장해 다음 요청에 빠르게 제공
  • CDN = 동네 분관 도서관: 전 세계 사용자 가까운 “엣지 서버”에 정적 파일을 복제해 거리 지연을 줄임

핵심은 이거예요.
브라우저는 ‘재다운로드’를 줄이고, 서버는 ‘재계산’을 줄이며, CDN은 ‘전송 거리’를 줄입니다.

아래 표로 한 번 더 정리해볼게요.

구분캐시 위치주로 캐시하는 것기대 효과주의할 점
브라우저 캐시사용자 브라우저이미지, CSS, JS, 폰트재방문 속도 개선, 트래픽 절감파일 업데이트 반영(버저닝) 필요
서버 캐시원본 서버HTML 페이지, 쿼리 결과(옵션)TTFB 개선, 서버 부하 감소로그인/개인화 페이지 예외 필수
CDN엣지 서버정적 파일(우선), 설정에 따라 HTML해외/모바일 체감 개선, 원서버 트래픽 감소쿠키/세션 섞이면 캐시 사고 가능

준비물/사전 체크

적용 전에 아래부터 확인하면 시행착오가 크게 줄어요.

  •  사이트에 로그인/회원 기능이 있는가? (있으면 예외 규칙 중요)
  •  우커머스 등 **장바구니/결제(/cart, /checkout)**가 있는가?
  •  캐시 플러그인을 2개 이상 동시에 쓰고 있지 않은가?(중복은 문제의 시작)
  •  정적 파일이 버전 쿼리(?ver=)를 갖고 있는가? (WP는 보통 갖습니다)
  •  CDN을 쓸 계획이라면, 정적 파일 경로(/wp-content//wp-includes/) 파악
  •  장애 대응을 위해 캐시 비활성화/퍼지(삭제) 방법을 미리 알고 있는가?

단계별 실행 가이드

1단계 브라우저 캐시: 정적 자산에 Cache-Control 기본값 잡기

a. 무엇을 하는지
CSS/JS/이미지 같은 정적 파일에 브라우저 캐시 정책을 붙여 재방문 시 재다운로드를 줄입니다.

b. 왜 하는지(원리/이유)
브라우저는 응답 헤더의 Cache-Control: max-age=...를 보고 “이 기간 동안은 다시 받지 말자”고 판단합니다.
정적 파일은 내용이 자주 바뀌지 않으니 캐시 기간을 길게 잡는 게 보통 유리합니다(단, 업데이트 반영 전략이 필요).

c. 예시(코드/설정)
Apache(.htaccess)에서 정적 확장자에 7일 캐시를 주는 예시입니다.

<IfModule mod_headers.c>
<FilesMatch "\.(css|js|png|jpg|jpeg|webp|svg|woff2?)$">
Header set Cache-Control "public, max-age=604800"
</FilesMatch>
</IfModule>

d. 흔한 실수와 해결법

  • 실수: 캐시를 길게 잡았더니 CSS 수정이 방문자에게 늦게 반영
    • 해결: 워드프레스는 보통 style.css?ver=버전 형태로 버전 쿼리를 붙입니다.
      테마/빌드 과정에서 파일명 해시(app.3a9f.css) 또는 ?ver=날짜를 활용하면 안전합니다.
  • 실수: HTML까지 브라우저 캐시로 오래 잡아버림
    • 해결: 브라우저 캐시는 정적 자산 중심으로 시작하세요.

2단계 서버 캐시: “페이지 캐시”를 한 곳에서만 켜기

a. 무엇을 하는지
서버가 생성한 HTML 결과를 저장해 두고, 다음 요청에 PHP/DB 실행 없이 바로 내려줍니다(비로그인 페이지 중심).

b. 왜 하는지(원리/이유)
워드프레스는 요청마다 PHP 실행 + DB 조회가 들어가면 쉽게 느려집니다.
페이지 캐시는 이 “재계산”을 줄여 TTFB와 서버 CPU 사용량을 떨어뜨립니다.

c. 예시(설정/스크린샷 설명)
캐시 플러그인(예: LiteSpeed Cache, WP Rocket 등)에서 보통 아래 옵션이 핵심입니다.

  • Page Cache: ON
  • Cache Logged-in Users: OFF(권장)
  • Exclude URLs: /wp-admin//wp-login.php/cart//checkout//my-account/

d. 흔한 실수와 해결법

  • 실수: 캐시 플러그인 2개(또는 서버 레벨 캐시+플러그인)를 동시에 켬
    • 해결: 페이지 캐시는 1군데에서만 관리하세요. 중복 캐시는 디버깅 난이도만 올립니다.
  • 실수: 로그인/회원 영역까지 캐시돼서 “내 정보가 다른 사람에게 보이는” 것처럼 보임(실제 노출 위험도 존재)
    • 해결: 로그인/개인화는 쿠키 기반 bypass가 필수입니다. 플러그인 예외 + 서버/CDN 규칙 둘 다 점검하세요.

3단계 CDN: 정적 파일부터 안전하게 캐시하고, 퍼지 전략 세우기

a. 무엇을 하는지
CDN을 붙여 /wp-content/ 이미지/JS/CSS 같은 정적 파일을 엣지에서 제공하게 합니다.

b. 왜 하는지(원리/이유)
사용자와 서버가 멀면 RTT(왕복 지연) 때문에 로딩이 늘어납니다.
CDN은 “가까운 서버”에서 내려줘서 해외/모바일 체감 속도를 개선하는 경우가 많습니다.

c. 예시(설정/규칙 예시)
CDN 캐시 룰을 이렇게 시작하면 비교적 안전합니다.

  • 캐시 대상: /wp-content/*/wp-includes/* (정적 자산 위주)
  • 캐시 제외: /wp-admin/*/wp-login.php
  • 쿠키 있는 요청: 기본적으로 캐시하지 않기(특히 HTML)

Nginx를 직접 운영한다면, 정적에 대한 헤더는 이런 식으로도 설정합니다.

location ~* \.(css|js|png|jpg|jpeg|webp|svg|woff2?)$ {
expires 7d;
add_header Cache-Control "public";
}

d. 흔한 실수와 해결법

  • 실수: CDN에서 HTML까지 무리하게 캐시해 로그인/댓글/폼 동작이 이상해짐
    • 해결: CDN은 정적부터, HTML 캐시는 충분히 이해하고 난 뒤에 단계적으로.
  • 실수: 글 수정 후에도 예전 이미지/JS가 보여서 “반영이 안 됨”
    • 해결: (1) 파일 버저닝 (2) CDN 퍼지(삭제) 버튼/자동 퍼지를 준비하세요.

주의사항(보안/성능 관련)

캐시는 성능에 도움 되지만, 잘못 설정하면 기능 오류 또는 보안 사고로 이어질 수 있습니다.

  • 로그인/회원/장바구니/결제/마이페이지는 캐시 예외가 기본입니다.
  • HTML 캐시를 적용할수록 쿠키/세션/개인화 분기가 중요해집니다.
  • 시작은 “정적 자산 캐시(브라우저+CDN) → 비로그인 페이지 캐시(서버)” 순서가 안전합니다.
  • 문제가 생기면 CDN → 서버 캐시 → 브라우저 캐시 순으로 끄고 원인을 좁히세요.

또 한 가지 균형 있게 말하면,

  • 트래픽이 적고 서버가 넉넉한 작은 사이트는 “과한 캐시”보다 운영 단순성이 더 이득일 수 있습니다.
  • 반대로 이미지 비중이 크거나 해외 유입이 많은 사이트는 CDN만으로도 체감 개선이 나오는 경우가 흔합니다.

실무 팁 현업에서 자주 쓰는 팁 5개

  1. 캐시는 레이어별로 하나씩만 켜고, 바꿀 때는 한 번에 하나만 변경합니다.
  2. 정적 파일은 캐시를 길게 주되, **버저닝(파일명 해시/?ver=)**을 함께 씁니다.
  3. “예외 URL 목록”은 운영 중 계속 늘어납니다. 로그인/폼/결제 관련 경로는 문서화해두세요.
  4. 캐시 이슈 디버깅은 시크릿 창 + 하드 리로드로 시작하고, 헤더(Cache-ControlAge)를 봅니다.
  5. 퍼지(삭제)는 수동으로만 두지 말고, 가능하면 글 발행/수정 시 자동 퍼지를 고려합니다.

검증 방법 적용 후 확인 방법(도구/체크 항목)

아래 3가지를 보면 “진짜로 캐시가 먹는지” 감이 잡힙니다.

  • Chrome DevTools → Network 탭
    • 정적 파일이 “(from disk cache)” 또는 “(from memory cache)”로 뜨는지 확인
    • 응답 헤더에 Cache-Control이 의도대로 들어갔는지 확인
  • curl로 헤더 확인
curl -I https://example.com/wp-content/themes/yourtheme/style.css
  • Cache-Controlexpires 확인
  • CDN/서버 캐시 히트 확인
    • CDN은 보통 Agex-cachecf-cache-status 같은 헤더로 히트를 알려줍니다(서비스마다 다름).
    • “MISS → HIT”로 바뀌는지 체크하세요.

FAQ

  1. 브라우저 캐시만 해도 되나요?
    정적 위주라면 효과가 있지만, TTFB가 느리면 서버 캐시도 고려하는 편이 좋습니다.
  2. 서버 캐시를 켰더니 로그인 상태가 꼬여요.
    로그인/회원 영역이 캐시되었을 가능성이 큽니다. 예외 URL과 “로그인 사용자 캐시 OFF”를 우선 점검하세요.
  3. CDN은 무조건 빨라지나요?
    대체로 정적 자산에는 도움이 되지만, 원서버가 이미 가까운 경우 체감이 작을 수 있습니다.
  4. 캐시 플러그인 2개를 같이 써도 되나요?
    권장하지 않습니다. 캐시 레이어 중복은 예측 불가능한 문제를 만들기 쉽습니다.
  5. 글 수정이 방문자에게 늦게 반영돼요.
    정적 자산은 버저닝, CDN은 퍼지, 서버 캐시는 페이지 캐시 삭제(퍼지) 동선을 마련하세요.
  6. 어떤 순서로 적용하는 게 안전한가요?
    정적(브라우저/CDN) → 비로그인 페이지 캐시(서버) 순서가 보통 안전합니다.

결론

브라우저 캐시, 서버 캐시, CDN은 서로 경쟁하는 기능이 아니라 역할이 다른 레이어입니다.
정적은 “다시 받지 않게”, 서버는 “다시 계산하지 않게”, CDN은 “가까이서 받게” 만드는 게 핵심이에요.

댓글 남기기