Gzip·Brotli 압축: 전송 크기 최적화
텍스트 기반 콘텐츠(HTML, CSS, JS, JSON)를 압축 전송하면 네트워크 전송량을 60~80% 줄이고 페이지 로딩 속도를 크게 개선할 수 있습니다. Nginx는 Gzip과 Brotli 두 가지 압축 방식을 지원합니다.
Gzip vs Brotli 비교
| 항목 | Gzip | Brotli |
|---|---|---|
| 표준화 | RFC 1952 (1996) | RFC 7932 (2016) |
| 압축률 | 기준 | 약 15~25% 더 높음 |
| 속도 | 빠름 | 레벨 1~4는 비슷, 고레벨은 느림 |
| 브라우저 지원 | 모든 브라우저 | 모던 브라우저 (IE 제외) |
| HTTPS 필요 여부 | 불필요 | 브라우저가 HTTPS에서만 요청 |
| 용도 | 범용 | 정적 파일 사전 압축에 탁월 |
Nginx Gzip 설정
# /etc/nginx/nginx.conf — http 블록
http {
# Gzip 활성화
gzip on;
# 최소 파일 크기 (이 이하는 압축 안 함 — 오히려 손해)
gzip_min_length 1024; # 1KB 미만은 압축 제외
# 압축 레벨: 1(빠름, 낮은 압축률) ~ 9(느림, 높은 압축률)
# 5~6이 CPU 효율과 압축률의 균형점
gzip_comp_level 5;
# 압축할 MIME 타입 (이미지·동영상은 이미 압축됨 → 제외)
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
application/rss+xml
image/svg+xml
font/ttf
font/woff
font/woff2;
# 프록시를 통해 온 요청에도 압축 적용
gzip_proxied any;
# Accept-Encoding에 따른 응답 캐시 분리 (Vary 헤더)
gzip_vary on;
# IE6 호환성 비활성화 (구형 브라우저 버그 방지)
gzip_disable "MSIE [1-6]\.";
# 압축 버퍼 설정
gzip_buffers 32 4k;
# HTTP 버전 (1.0도 압축 적용)
gzip_http_version 1.0;
}
Nginx Brotli 설정
Brotli는 별도 모듈이 필요합니다. Ubuntu에서는 libnginx-mod-http-brotli-filter로 설치합니다.
# Ubuntu
sudo apt install libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static
# 또는 nginx 소스에서 컴파일
# --add-module=/path/to/ngx_brotli
# /etc/nginx/nginx.conf — http 블록
http {
# Brotli 동적 압축
brotli on;
brotli_comp_level 4; # 0~11, 4~6 권장 (CPU 효율)
brotli_min_length 1024;
brotli_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml;
}
사전 압축(Pre-compression) — 최고 성능
정적 파일은 요청마다 압축하지 않고 배포 시점에 미리 압축해두면 CPU 비용 없이 압축 파일을 제공할 수 있습니다.
# 배포 파이프라인에서 사전 압축
gzip -9 -k /var/www/html/static/app.js # app.js.gz 생성
brotli -9 -k /var/www/html/static/app.js # app.js.br 생성
# Nginx — 사전 압축 파일 자동 선택
server {
location ~* \.(css|js|html|json|svg)$ {
root /var/www/html;
# .br → .gz → 원본 순서로 자동 선택
brotli_static on; # app.js.br 존재하면 사용
gzip_static on; # app.js.gz 존재하면 사용
}
}
Apache Gzip 설정 (mod_deflate)
# mod_deflate 활성화
sudo a2enmod deflate
# /etc/apache2/conf-available/compression.conf
<IfModule mod_deflate.c>
# 압축 활성화
SetOutputFilter DEFLATE
# 압축 레벨 (1~9)
DeflateCompressionLevel 5
# 압축할 MIME 타입
AddOutputFilterByType DEFLATE text/html text/css text/javascript
AddOutputFilterByType DEFLATE application/javascript application/json
AddOutputFilterByType DEFLATE application/xml image/svg+xml
# Vary 헤더 추가 (캐시 서버에서 압축/비압축 구분)
Header append Vary Accept-Encoding
# 이미 압축된 파일 제외
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png|zip|gz|bz2|woff2)$ no-gzip dont-vary
# 구형 브라우저 대응
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
</IfModule>
압축 효과 측정
# 압축 전후 크기 비교
curl -s -H "Accept-Encoding: gzip" https://example.com/api/products \
-o /dev/null -w "Size: %{size_download} bytes, Time: %{time_total}s\n"
curl -s https://example.com/api/products \
-o /dev/null -w "Size: %{size_download} bytes, Time: %{time_total}s\n"
# 압축 헤더 확인
curl -I -H "Accept-Encoding: gzip, br" https://example.com/static/app.js
# Content-Encoding: br ← Brotli 압축 사용
# Content-Encoding: gzip ← Gzip 압축 사용
# 실제 압축률 테스트
echo "원본 크기:"
wc -c /var/www/html/static/app.js
echo "Gzip 압축 크기:"
gzip -c -9 /var/www/html/static/app.js | wc -c
echo "Brotli 압축 크기:"
brotli -c -9 /var/www/html/static/app.js | wc -c
압축 대상 선택 전략
# 압축하면 안 되는 파일 타입
# - JPEG, PNG, WebP, AVIF: 이미 압축된 이미지
# - ZIP, GZ, BR, WOFF2: 이미 압축된 파일
# - 동영상(MP4, WebM): 이미 압축됨
# - 암호화된 데이터: 압축 효과 없음
# 압축해야 하는 파일 타입
# - HTML: 50~70% 절감
# - CSS: 60~80% 절감
# - JavaScript: 60~80% 절감
# - JSON API 응답: 60~90% 절감 (반복 패턴이 많을수록)
# - SVG: 70~90% 절감 (XML 기반)
압축 성능 최적화 팁
# 대용량 파일 처리 개선
http {
gzip_comp_level 1; # 대용량 파일은 낮은 레벨로 CPU 절약
gzip_min_length 10240; # 10KB 이상만 압축 (소용량 파일은 오버헤드)
# 동적 응답만 실시간 압축, 정적 파일은 gzip_static으로
location /api/ {
proxy_pass http://backend;
gzip on;
gzip_comp_level 5;
}
location /static/ {
root /var/www;
gzip_static on; # 사전 압축 파일 사용
brotli_static on;
expires 1y;
}
}