Nginx로 정적 자산 캐싱하여 빠른 웹사이트 만들기

Web2026-09-21TryQuickToolBox

정적 자산 캐싱이 중요한 이유

사용자가 웹사이트를 방문할 때마다 브라우저는 CSS 파일, JavaScript, 이미지, 폰트 등 수십 개의 정적 자산을 요청합니다. 적절한 캐싱이 없으면 각 요청이 서버에 도달하여 로드 시간과 대역폭 사용량이 증가합니다. 고성능 웹 서버인 Nginx는 브라우저가 이러한 자산을 로컬에 캐시하도록 지시하고 서버 측에서도 캐시함으로써 이를 극적으로 개선할 수 있습니다.

이 가이드에서는 Nginx를 구성하여 정적 자산을 효과적으로 캐시하고 지연 시간과 서버 부하를 줄이는 방법을 배웁니다.

브라우저 캐싱 vs. 서버 측 캐싱 이해하기

여기서 관련된 두 가지 주요 캐싱 유형이 있습니다:

둘 다 성능에 중요합니다. 우리는 둘 다 다룰 것입니다.

1단계: Expires 헤더로 브라우저 캐싱 구성하기

브라우저 캐싱을 활성화하는 가장 간단한 방법은 Nginx 구성에 expires 지시문을 추가하는 것입니다. 이는 Expires 및 Cache-Control 헤더를 설정합니다.

사이트의 구성 파일(예: /etc/nginx/sites-available/example.com)을 열고 정적 자산에 대한 location 블록을 추가하세요:

location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

이것은 브라우저에게 이 파일들을 1년 동안 캐시하도록 지시합니다. immutable 지시문은 파일이 절대 변경되지 않을 것임을 나타내므로 브라우저는 새로고침 시 재검증조차 하지 않습니다.

모범 사례: 버전이 지정된 파일 이름(예: style.abc123.css)을 사용하여 캐싱을 깨지 않고 자산을 업데이트할 수 있습니다. 파일이 변경되면 파일 이름이 변경되고 브라우저는 새 버전을 가져옵니다.

2단계: 프록시 캐시로 서버 측 캐싱 활성화하기

Nginx 뒤에서 애플리케이션 서버(예: Node.js, Python 또는 PHP)를 실행 중인 경우 Nginx에서 정적 응답을 캐시하여 백엔드 요청을 줄일 수 있습니다.

먼저 nginx.conf의 http 블록에서 캐시 경로를 정의하세요:

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static_cache:10m max_size=1g inactive=60m use_temp_path=off;

그런 다음 서버 블록에서 사용하세요:

location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg)$ {
    proxy_cache static_cache;
    proxy_cache_valid 200 302 1y;
    proxy_cache_valid 404 1m;
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    proxy_cache_lock on;
    add_header X-Cache-Status $upstream_cache_status;
    proxy_pass http://backend;
}

이것은 성공적인 응답을 1년 동안 캐시하고 백엔드가 다운된 경우 오래된 콘텐츠를 제공합니다. X-Cache-Status 헤더는 디버깅에 도움이 됩니다(HIT, MISS 등).

3단계: 압축 및 HTTP/2로 최적화하기

캐싱은 요청을 줄이지만 gzip 압축과 HTTP/2를 활성화하여 전송 속도를 더 높일 수 있습니다.

nginx.conf에서 gzip을 활성화하세요:

gzip on;
gzip_types text/css application/javascript image/svg+xml;
gzip_min_length 1000;

HTTP/2는 요청을 다중화하며 listen 지시문에 http2를 추가하여 활성화됩니다:

listen 443 ssl http2;

참고: HTTP/2는 HTTPS가 필요합니다. 아직 TLS를 설정하지 않았다면 HTTPS와 TLS가 실제로 작동하는 방식에 대한 가이드를 참조하세요.

비교: Cache-Control 지시문

지시문 의미 권장 대상
public 응답은 모든 캐시에 의해 캐시될 수 있음 정적 자산
private 응답은 단일 사용자를 위한 것 사용자별 데이터
no-cache 서버와 재검증해야 함 HTML 페이지
no-store 절대 캐시하지 않음 민감한 데이터
immutable 콘텐츠가 변경되지 않음 버전이 지정된 자산

4단계: 테스트 및 검증하기

변경 사항을 적용한 후 Nginx를 다시 로드하세요: sudo nginx -s reload. 그런 다음 curl로 테스트하세요:

curl -I https://example.com/style.css

Cache-Control 및 Expires 헤더를 확인하세요. 브라우저 DevTools(Network 탭)를 사용하여 자산이 캐시에서 제공되는지(상태 200 또는 304) 확인할 수도 있습니다.

서버 측 캐시의 경우 X-Cache-Status 헤더를 모니터링하세요.

일반적인 함정과 모범 사례

자주 묻는 질문

자산이 캐시되고 있는지 어떻게 알 수 있나요?

curl -I 또는 브라우저 DevTools로 응답 헤더를 확인하세요. Cache-Control: public, max-age=31536000 및 Expires 헤더를 찾으세요. DevTools에서 Size 열은 캐시된 자산에 대해 "(from disk cache)"를 표시합니다.

expires와 Cache-Control의 차이점은 무엇인가요?

expires는 절대 날짜를 설정하는 반면 Cache-Control은 상대 초를 사용합니다. 최신 브라우저에서는 Cache-Control이 우선합니다. Nginx의 expires 지시문은 호환성을 위해 둘 다 설정합니다.

동적 콘텐츠를 캐시할 수 있나요?

예, 하지만 주의해야 합니다. 짧은 TTL로 proxy_cache를 사용하고 쿠키나 헤더를 기반으로 한 캐시 키를 고려하세요. 사용자별 콘텐츠의 경우 private을 사용하거나 캐싱을 피하세요.

TryQuickToolBox로 워크플로우 속도 높이기

사이트 성능을 최적화하는 동안 이미지나 PDF를 압축해야 할 수 있습니다. 이미지 압축기를 사용하여 품질 손실 없이 이미지 크기를 줄여 Nginx 캐싱 전략을 보완하세요.