네트워크/HTTP

HTTP 캐싱 완벽 가이드: 웹 성능 최적화의 핵심

shimdh 2025. 3. 4. 09:59
728x90

1. HTTP 캐싱의 기본 개념

1.1 캐시의 정의와 목적

캐시는 자주 사용되는 데이터의 사본을 저장하는 임시 저장소입니다. 웹 환경에서 캐시는 다음과 같은 이점을 제공합니다:

  • 성능 향상

    • 페이지 로드 시간 단축
    • 서버 응답 대기 시간 감소
    • 사용자 경험 개선
  • 리소스 절약

    • 서버 부하 감소
    • 네트워크 대역폭 절약
    • 비용 효율성 증가

1.2 캐시의 종류

  1. 브라우저 캐시

    • 사용자의 로컬 디스크에 저장
    • 가장 빠른 응답 시간 제공
    • 개인화된 캐싱 가능
  2. 프록시 캐시

    • 네트워크 중간에 위치
    • 여러 사용자가 공유
    • ISP나 기업에서 주로 운영
  3. CDN (Content Delivery Network)

    • 전 세계적으로 분산된 캐시 서버
    • 지리적 위치 기반 최적화
    • 대규모 트래픽 처리에 효과적

2. HTTP 캐싱 메커니즘

2.1 캐시 제어 헤더

Cache-Control 헤더

Cache-Control: max-age=3600, public
Cache-Control: no-cache
Cache-Control: private, max-age=0
Cache-Control: no-store

주요 디렉티브:

  • public: 모든 캐시가 응답을 저장 가능
  • private: 브라우저만 캐시 가능
  • no-cache: 재검증 필요
  • no-store: 캐시 저장 금지
  • max-age: 캐시 유효 기간 (초)
  • s-maxage: 공유 캐시 유효 기간
  • must-revalidate: 만료 시 반드시 재검증

ETag와 Last-Modified

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT

2.2 조건부 요청

If-None-Match

GET /resource HTTP/1.1
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

If-Modified-Since

GET /resource HTTP/1.1
If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT

3. 캐싱 전략

3.1 정적 리소스 캐싱

# 이미지, CSS, JavaScript 파일
Cache-Control: public, max-age=31536000, immutable

3.2 동적 컨텐츠 캐싱

# API 응답
Cache-Control: private, max-age=0, must-revalidate
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

3.3 버전 기반 캐싱


<link rel="stylesheet" href="/styles.123abc.css">
<script src="/app.456def.js"></script>

4. 캐시 무효화 전략

4.1 즉시 무효화

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0

4.2 버전 관리

// 파일명 변경
const filename = `style.${hash}.css`;

// URL 파라미터 사용
const url = `/api/data?v=${version}`;

5. 브라우저별 캐시 구현

5.1 Chrome

// Service Worker를 통한 캐시 제어
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
  );
});

5.2 Firefox

// IndexedDB를 활용한 캐시 구현
const request = indexedDB.open("CacheDB", 1);
request.onupgradeneeded = event => {
  const db = event.target.result;
  db.createObjectStore("responses", { keyPath: "url" });
};

6. 성능 모니터링

6.1 캐시 히트율 측정

const cacheMetrics = {
  hits: 0,
  misses: 0,

  get hitRate() {
    return this.hits / (this.hits + this.misses);
  }
};

6.2 응답 시간 모니터링

const startTime = performance.now();
fetch('/api/data')
  .then(response => {
    const endTime = performance.now();
    console.log(`Response time: ${endTime - startTime}ms`);
    return response.json();
  });

7. 최적화 기법

7.1 레이어드 캐싱

Browser Cache -> CDN -> Edge Cache -> Origin Server

7.2 프리페칭

<link rel="prefetch" href="/next-page.html">
<link rel="preload" href="/critical.js" as="script">

8. 일반적인 문제와 해결방안

8.1 캐시 불일치

// 버전 기반 캐시 무효화
const cacheVersion = 'v1';
const cacheKey = `myapp-${cacheVersion}`;

// 이전 버전 캐시 삭제
caches.keys().then(keys => {
  keys.forEach(key => {
    if (key !== cacheKey) {
      caches.delete(key);
    }
  });
});

8.2 프라이버시 이슈

# 민감한 데이터
Cache-Control: private, no-store

결론

HTTP 캐싱은 웹 애플리케이션의 성능을 최적화하는 핵심 요소입니다. 효과적인 캐싱 전략을 구현하기 위해서는 다음 사항들을 고려해야 합니다:

  1. 리소스 특성 파악

    • 정적/동적 컨텐츠 구분
    • 업데이트 빈도
    • 보안 요구사항
  2. 사용자 패턴 분석

    • 접근 빈도
    • 지리적 분포
    • 디바이스 특성
  3. 인프라 구조 최적화

    • CDN 활용
    • 엣지 캐싱 구현
    • 캐시 계층화

적절한 캐싱 전략을 통해 웹 애플리케이션의 성능을 크게 향상시킬 수 있으며, 이는 곧 더 나은 사용자 경험과 비즈니스 성과로 이어질 수 있습니다.

728x90