정적 파일은 압축되는데 API 응답만 압축되지 않은 이유
문제 발생
gzip on;을 넣었는데 JSON API 응답의 Content-Encoding이 비어 있었습니다. HTML은 압축되고 있었습니다.
$ curl -H "Accept-Encoding: gzip" -I https://dev.meokko.com/api/posts
# Content-Encoding 없음원인 분석
세 가지 기본값이 겹쳐 있습니다. nginx 문서의 기본값을 보면 이유가 한 번에 드러납니다.
gzip기본값은off— 켜지 않으면 아무것도 압축하지 않습니다.gzip_types기본값은text/html— 켜도 HTML만 대상입니다. JSON, CSS, JS는 명시해야 합니다.gzip_proxied기본값은off— 프록시된 요청에 대한 압축이 기본적으로 비활성입니다.
우리 구성에서 HTML은 nginx가 직접 서빙하고 API는 upstream(Next.js)으로 프록시되므로, 딱 프록시된 응답만 빠진 것입니다.
해결 방안
- 세 가지를 함께 설정합니다.
gzip on;
gzip_types application/json application/javascript text/css text/plain image/svg+xml;
gzip_proxied any;
gzip_min_length 1024;-
작은 응답은 압축하지 않습니다.
gzip_min_length기본값은 20바이트인데, 수백 바이트 응답은 압축 이득보다 CPU와 헤더 오버헤드가 큽니다 — 1KB 안팎이 흔한 기준입니다. -
이미 압축된 형식을 빼둡니다. JPEG·PNG·WebP·zip은 다시 압축해도 줄지 않습니다.
gzip_types에 넣지 않습니다. -
Vary: Accept-Encoding을 확인합니다. 압축 여부가 응답을 바꾸므로 캐시가 이를 알아야 합니다 — nginx가 붙여주는지, CDN이 유지하는지 확인합니다. -
upstream이 이미 압축했는지 봅니다. 애플리케이션이 자체 압축을 하고 있으면 nginx는 그대로 통과시킵니다 — 두 곳에서 켜면 CPU만 이중으로 씁니다. 한 곳에서만 합니다.
-
실제 응답으로 검증합니다.
curl -H "Accept-Encoding: gzip" -I로Content-Encoding: gzip이 오는지 확인하고, 전송 크기를 비교합니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.