Gzip vs Brotli 압축 방식 비교와 웹 성능 최적화 적용법
웹 페이지의 로딩 속도를 개선하는 가장 효과적이면서도 간단한 방법 중 하나는 텍스트 기반 리소스를 압축하는 것입니다. HTML, CSS, JavaScript는 압축률이 높아 용량을 60~80% 줄일 수 있습니다. 현재 웹에서 가장 널리 사용되는 압축 알고리즘은 Gzip과 Brotli입니다. 이번 글에서는 두 압축 방식의 차이와 실무 적용법을 상세히 정리해 드리겠습니다.
웹 압축이란?
웹 압축은 서버가 응답을 보내기 전에 텍스트 데이터를 압축하여 전송 용량을 줄이는 기술입니다. 브라우저는 압축된 데이터를 받아 해제하여 사용합니다. 네트워크 대역폭을 절약하고, 특히 모바일 환경에서 로딩 속도를 크게 개선합니다.
// 압축 전 (원본)
Content-Length: 150000 bytes
Transfer-Encoding: chunked
// 압축 후 (Brotli)
Content-Length: 28000 bytes
Content-Encoding: br
Gzip이란?
Gzip은 1992년에 개발된 DEFLATE 알고리즘 기반의 압축 방식입니다. HTTP/1.1부터 표준으로 채택되어 현재까지 가장 널리 지원됩니다. 압축 속도가 빠르고 CPU 부하가 적어 서버 성능에 부담을 주지 않습니다.
// Gzip 압축 과정
1. LZ77 알고리즘으로 반복되는 문자열을 슬라이딩 윈도우에서 찾음
2. Huffman 코딩으로 빈번한 문자에 짧은 코드 할당
3. 압축된 데이터 + 헤더 생성
// 압축률: 일반적으로 60~70%
Brotli란?
Brotli는 2015년 Google이 개발한 차세대 압축 알고리즘입니다. 사전(dictionary)에 웹에서 자주 사용하는 단어와 구문을 미리 저장하여, Gzip보다 더 높은 압축률을 달성합니다.
// Brotli 압축 과정
1. LZ77 변형 알고리즘으로 문자열 매칭
2. 2차 컨텍스트 모델링으로 문자 예측
3. 12,000+ 단어의 정적 사전 활용 (HTML, CSS, JS 키워드 포함)
4. Huffman 코딩 적용
// 압축률: 일반적으로 70~80% (Gzip 대비 15~25% 향상)
Gzip vs Brotli 상세 비교
| 항목 | Gzip | Brotli |
|---|---|---|
| 개발사 | Jean-loup Gailly, Mark Adler | |
| 출시 연도 | 1992 | 2015 |
| 알고리즘 | DEFLATE (LZ77 + Huffman) | LZ77 변형 + 2차 컨텍스트 모델링 + 정적 사전 |
| 압축률 | 60~70% | 70~80% (Gzip 대비 15~25% 우수) |
| 압축 속도 | 빠름 | 느림 (압축 레벨에 따라 다름) |
| 해제 속도 | 빠름 | 빠름 (Gzip과 유사 또는 더 빠름) |
| CPU 부하 | 낮음 | 중간~높음 (압축 시) |
| 브라우저 지원 | 100% | 95%+ (IE 제외) |
| Content-Encoding | gzip | br |
실제 압축률 비교
실제 웹 리소스에 대한 압축률 비교입니다. (압축 레벨: Gzip 6, Brotli 4)
| 파일 유형 | 원본 크기 | Gzip | Brotli | 절감률 |
|---|---|---|---|---|
| HTML | 150 KB | 45 KB | 35 KB | 22% 추가 절감 |
| CSS | 200 KB | 38 KB | 28 KB | 26% 추가 절감 |
| JavaScript | 500 KB | 120 KB | 90 KB | 25% 추가 절감 |
| JSON API 응답 | 80 KB | 18 KB | 14 KB | 22% 추가 절감 |
Nginx에서 적용하기
🔧 Gzip 설정
# /etc/nginx/nginx.conf
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6; # 1~9 (높을수록 압축률 ↑, 속도 ↓)
gzip_min_length 1024; # 1KB 이상만 압축
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/json
application/xml
application/rss+xml
font/truetype
font/opentype
application/vnd.ms-fontobject
image/svg+xml;
🔧 Brotli 설정
Nginx는 기본적으로 Brotli를 지원하지 않으므로, ngx_brotli 모듈을 추가해야 합니다.
# ngx_brotli 모듈 설치 (Ubuntu)
sudo apt install libnginx-mod-brotli
# /etc/nginx/nginx.conf
brotli on;
brotli_comp_level 6; # 1~11 (높을수록 압축률 ↑, CPU 부하 ↑)
brotli_min_length 1024;
brotli_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/json
application/xml
application/rss+xml
font/truetype
font/opentype
application/vnd.ms-fontobject
image/svg+xml;
# Gzip과 Brotli 함께 사용 (Brotli 우선, 미지원 시 Gzip fallback)
gzip on;
gzip_vary on;
Node.js Express에서 적용하기
const express = require('express');
const compression = require('compression');
const expressStaticGzip = require('express-static-gzip');
const app = express();
// Gzip 동적 압축 (실시간)
app.use(compression({
level: 6,
filter: (req, res) => {
if (req.headers['x-no-compression']) return false;
return compression.filter(req, res);
}
}));
// Brotli + Gzip 정적 파일 서빙 (미리 압축된 파일)
app.use('/', expressStaticGzip('dist', {
enableBrotli: true,
orderPreference: ['br', 'gzip'],
serveStatic: {
maxAge: '1y',
immutable: true
}
}));
정적 파일 미리 압축하기
빌드 시점에 미리 압축하면 서버 CPU 부하를 줄이고 응답 속도를 향상시킬 수 있습니다.
# Webpack 설정 (compression-webpack-plugin)
npm install compression-webpack-plugin --save-dev
// webpack.config.js
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
plugins: [
// Gzip
new CompressionPlugin({
filename: '[path][base].gz',
algorithm: 'gzip',
test: /\.(js|css|html|svg)$/,
threshold: 10240,
minRatio: 0.8,
}),
// Brotli
new CompressionPlugin({
filename: '[path][base].br',
algorithm: 'brotliCompress',
test: /\.(js|css|html|svg)$/,
compressionOptions: { level: 11 },
threshold: 10240,
minRatio: 0.8,
}),
],
};
압축 레벨 튜닝
압축 레벨은 압축률과 CPU 사용량의 트레이드오프입니다. 실무에서는 다음 기준을 권장합니다.
| 상황 | Gzip 레벨 | Brotli 레벨 |
|---|---|---|
| 동적 압축 (서버에서 실시간) | 4~6 | 4~6 |
| 정적 압축 (빌드 시 미리) | 9 | 11 |
| CPU 제한 환경 | 1~3 | 1~3 |
| 최대 압축률 우선 | 9 | 11 |
자주 하는 실수와 해결책
❌ 이미 압축된 파일 재압축
이미지, 동영상, PDF 등은 이미 압축된 형식입니다. Gzip이나 Brotli로 재압축해도 용량이 줄지 않고, 오히려 CPU만 낭비합니다.
# ❌ 잘못된 설정
gzip_types image/jpeg image/png video/mp4;
# ✅ 올바른 설정 (텍스트 기반만 압축)
gzip_types text/plain text/css application/javascript application/json;
❌ 너무 작은 파일 압축
압축 헤더 오버헤드 때문에 1KB 미만 파일은 압축해도 이득이 없습니다. gzip_min_length나 brotli_min_length로 임계값을 설정하세요.
❌ ETag 충돌
압축된 응답과 비압축 응답의 ETag가 달라져 캐싱 문제가 발생할 수 있습니다. gzip_vary on으로 Vary: Accept-Encoding 헤더를 추가하세요.
# 응답 헤더 확인
HTTP/1.1 200 OK
Content-Encoding: br
Vary: Accept-Encoding
Content-Length: 28000
실무 체크리스트
- ✅ Brotli 우선, Gzip fallback으로 설정 (Brotli 지원 브라우저 95%+)
- ✅ 정적 파일은 빌드 시 미리 압축하여 서버 CPU 절약
- ✅ 동적 압축은 레벨 4~6으로 CPU 부하와 압축률 균형
- ✅ 이미지/동영상 등 이미 압축된 파일은 제외
- ✅ min_length로 1KB 이하 파일 압축 방지
- ✅ Vary: Accept-Encoding 헤더로 캐싱 정확성 보장
- ✅ CDN(Cloudflare, AWS CloudFront)에서 자동 압축 활용 검토
- ✅ 압축률 모니터링으로 실제 절감 효과 측정
자주 묻는 질문
Brotli를 쓰면 Gzip은 완전히 제거하나요?
아니요. Brotli를 우선순위로 두고 Gzip은 fallback으로 유지하는 것이 좋습니다. 일부 구형 브라우저나 API 클라이언트가 Brotli를 지원하지 않을 수 있습니다. Accept-Encoding 헤더를 확인하여 적절한 형식을 서빙하세요.
압축으로 인한 CPU 부하가 걱정돼요
정적 파일은 빌드 시 미리 압축하면 서버 CPU 부하를 거의 제거할 수 있습니다. 동적 응답의 경우, 압축 레벨을 낮추거나, CDN에서 압축을 위임하는 것을 고려하세요. 대부분의 경우 압축으로 절약되는 네트워크 대역폭이 CPU 부하보다 이득이 큽니다.
API 응답도 압축해야 하나요?
네, 특히 대용량 JSON 응답은 압축 효과가 큽니다. REST API나 GraphQL 응답이 10KB를 초과하면 압축을 적용하세요. 다만 서버 간 내부 통신(gRPC 등)에서는 이미 바이너리 프로토콜을 사용하므로 추가 압축이 필요 없습니다.
마무리
이번 글에서는 Gzip vs Brotli 압축 방식 비교와 웹 성능 최적화 적용법을 정리해 드렸습니다. 압축은 구현이 간단하면서도 로딩 속도에 큰 영향을 주는 핵심 최적화 기법입니다.
핵심을 정리하면 다음과 같습니다: Brotli가 Gzip보다 15~25% 더 높은 압축률을 제공하며, 정적 파일은 빌드 시 미리 압축하고, 동적 응답은 레벨 4~6으로 균형을 맞추며, 이미 압축된 파일은 제외하고, Brotli 우선 Gzip fallback으로 브라우저 호환성을 확보하세요.
웹 압축 최적화 관련 궁금한 점이나 문제가 있으시면 댓글로 남겨 주세요. 도움이 되셨다면 이 글을 주변에 공유해 주시는 것도 잊지 마세요!


댓글 0
첫 댓글을 남겨보세요.