Nginx 압축 마스터하기: 웹 성능을 위한 Gzip vs. Brotli

Gzip과 Brotli 알고리즘을 비교하여 Nginx 콘텐츠 압축을 마스터하세요. 두 가지를 모두 활성화하는 실용적인 구성 지시문을 배우고, 성능 트레이드오프를 이해하며, 정적 Brotli 파일을 사용하여 대역폭 사용량을 크게 줄이고 웹 서버에서 콘텐츠 전송을 가속화하는 모범 사례를 알아보세요.

Nginx 압축 마스터하기: 웹 성능을 위한 Gzip vs. Brotli

Nginx 압축은 네트워크 패널을 확인하기 전까지는 사소한 변경처럼 느껴집니다. CSS 파일, JavaScript 번들, HTML 페이지, JSON API 응답 또는 SVG는 종종 훨씬 더 작은 응답으로 네트워크를 통해 전송된 후 브라우저에서 동일한 콘텐츠로 다시 확장될 수 있습니다.

실용적인 선택은 일반적으로 "영원히 Gzip 또는 Brotli"가 아닙니다. 대부분의 프로덕션 설정은 둘 다 사용합니다. Brotli는 이를 요청하는 브라우저용, Gzip은 대체 수단으로, 그리고 빌드 파이프라인이 미리 생성할 수 있는 사전 압축 정적 파일을 사용합니다. 그러나 세부 사항이 중요합니다. 복사된 압축 블록은 CPU를 낭비하거나, 중요한 MIME 유형을 건너뛰거나, Brotli 모듈이 실제로 설치되지 않았기 때문에 자동으로 실패할 수 있습니다.

Nginx에서 웹 압축 이해하기

압축은 데이터(HTML, CSS 또는 JavaScript 파일 등)에서 반복되는 패턴을 찾아 더 짧은 참조로 대체하여 작동합니다. 이렇게 하면 네트워크를 통해 전송되는 파일의 전체 크기가 줄어듭니다. Nginx는 중개자 역할을 하여 데이터를 브라우저로 보내기 전에 선택한 압축 알고리즘을 동적으로 적용합니다.

Nginx는 일반적으로 Gzip을 위해 ngx_http_gzip_module이 필요하고 Brotli를 위해 별도의 Brotli 모듈이 필요합니다. 대부분의 일반적인 Nginx 패키지에는 Gzip 지원이 포함되어 있습니다. Brotli는 더 다양합니다. 일부 배포판에서는 동적 모듈로 패키징하고, 일부 타사 리포지토리에는 포함되어 있으며, 일부 빌드에는 전혀 없습니다.

전제 조건

Brotli를 사용하려면 Nginx 설치가 Brotli를 지원하는지 확인하세요. 다음을 실행하여 Brotli를 사용할 수 있는지 확인할 수 있습니다.

nginx -V 2>&1 | grep -i brotli

출력에 Brotli가 언급되면 컴파일되었는지 또는 동적 모듈로 로드되었는지 확인하세요. Debian 또는 Ubuntu 계열 시스템에서 패키지가 동적 모듈을 사용하는 경우 /etc/nginx/modules-enabled/ 아래의 파일도 확인하세요.

ls -l /etc/nginx/modules-enabled/ | grep -i brotli

nginx -t 중에 Nginx가 brotli on;을 거부하면 운영 체제에 Brotli 패키지가 다른 곳에 설치되어 있어도 해당 실행 중인 Nginx 바이너리에서 모듈을 사용할 수 없는 것입니다.

1. Gzip 압축 구성

Gzip은 콘텐츠 압축을 위한 성숙하고 널리 지원되는 표준입니다. 압축률과 CPU 오버헤드 사이에서 좋은 균형을 제공합니다.

Nginx 구성에서 Gzip 활성화

Gzip 설정은 일반적으로 Nginx 구성 파일(nginx.conf 또는 포함된 구성 파일)의 http, server 또는 location 블록 내에 배치됩니다.

Gzip 압축을 활성화하려면 다음 지시문을 사용하세요.

http {
    # Gzip 압축 활성화
    gzip on;

    # 압축할 최소 응답 크기 설정 (바이트)
    # 1000바이트보다 큰 파일만 압축
    gzip_min_length 1000;

    # 압축 수준 (1=가장 빠름/가장 낮은 압축, 9=가장 느림/가장 높은 압축)
    gzip_comp_level 6;

    # 압축할 MIME 유형 지정
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;

    # 권장: 프록시가 압축 및 비압축 버전을 모두 캐시할 수 있도록 Vary: Accept-Encoding 헤더 전송
    gzip_vary on;

    # 권장: 식별을 위한 gzip 헤더 추가
    gzip_proxied any;
}

주요 Gzip 지시문 설명

  • gzip on;: Gzip 모듈을 활성화합니다.
  • gzip_comp_level: 4에서 6 사이로 설정하는 것이 성능에 가장 적합한 경우가 많습니다. 더 높은 수준은 대역폭을 더 절약하지만 서버의 CPU 사용량을 증가시킵니다.
  • gzip_types: 중요하게도, 이미 압축된 형식(예: 이미지 .jpg, .png, .gif 또는 비디오)은 절대 압축하지 마세요.

2. Brotli 압축 구성

Brotli는 Google이 개발한 최신 압축 알고리즘입니다. 텍스트 자산의 경우 Gzip보다 더 작은 파일을 생성하는 경우가 많습니다. 정확한 이득은 콘텐츠, 압축 수준, 파일이 각 요청 중에 압축되는지 아니면 배포 중에 미리 압축되는지에 따라 다릅니다.

Nginx 구성에서 Brotli 활성화

Brotli 구성은 유사한 지시문을 사용하지만 gzipbrotli로 대체합니다.

brotli on;
brotli_comp_level 6; # 일반적으로 4에서 8이 권장됨
brotli_static on; # 사용 가능한 경우 사전 압축된 .br 파일 제공 활성화
brotli_types text/plain text/css application/json application/javascript application/x-javascript text/xml;

사전 압축(brotli_static)에 대한 중요 참고 사항:

Brotli 압축은 모든 요청에 대해 실시간으로 수행될 때 CPU 집약적일 수 있습니다. 일반적인 모범 사례는 전용 오프라인 도구(brotli 명령줄 유틸리티 등)를 사용하여 자산을 사전 압축하고 원본 파일(예: style.cssstyle.css.br)과 함께 .br 버전을 저장하는 것입니다.

brotli_static on;을 설정하면 Nginx가 요청된 리소스에 대해 사전 압축된 .br 파일이 있는지 확인하고 클라이언트가 Brotli를 지원하는 경우 실시간 처리를 완전히 우회하여 직접 제공하도록 지시합니다.

3. Gzip vs. Brotli: 올바른 선택

Gzip과 Brotli 중에서 선택하는 것은 클라이언트 지원과 서버 리소스에 크게 좌우됩니다.

기능 Gzip Brotli 권장 사항
압축률 좋음 텍스트 자산의 경우 종종 더 좋음 Brotli가 일반적으로 우세
CPU 부하 (실시간) 낮음 보통에서 높음 Gzip이 더 가벼움
클라이언트 지원 거의 보편적 (모든 최신 브라우저) 매우 높음 (대부분의 최신 브라우저) 레거시 지원을 위해 Gzip이 더 안전
사전 압축 가능하지만 덜 일반적 매우 권장됨 (brotli_static) 가능하면 Brotli 사전 압축 사용

하이브리드 접근 방식: 모범 사례

가장 강력한 최신 구성은 하이브리드 설정을 사용하여 최신 클라이언트를 위해 Brotli를 우선시하고 안정적인 대체 수단으로 Gzip을 제공합니다.

  1. Brotli 우선 순위 지정: Brotli를 먼저 구성하고, 속도를 위해 brotli_static on;을 자주 사용합니다.
  2. Gzip으로 대체: Gzip이 활성화되어 있고 Brotli를 지원하지 않는 클라이언트를 처리하도록 구성되었는지 확인합니다.

Nginx는 클라이언트의 Accept-Encoding 헤더와 빌드에서 활성화된 모듈을 기반으로 응답을 선택합니다. 일반적인 브라우저 트래픽에서 클라이언트가 br을 알리면 Brotli가 선호됩니다. Gzip은 gzip만 요청하는 클라이언트, 도구, 프록시 및 이전 스택에 유용합니다.

하이브리드 구성 예시

Nginx 버전이 두 모듈을 모두 지원하는 경우 동시에 활성화할 수 있습니다. Nginx는 클라이언트의 요청 헤더를 기반으로 어떤 모듈이 콘텐츠를 제공할지 우선 순위를 지정합니다.

http {
    # --- Brotli 구성 ---
    brotli on;
    brotli_comp_level 6;
    brotli_static on;
    brotli_types
        text/plain
        text/css
        application/javascript
        application/json
        application/xml
        image/svg+xml;

    # --- Gzip 구성 (대체) ---
    gzip on;
    gzip_comp_level 5;
    gzip_vary on;
    gzip_proxied any;
    gzip_types
        text/plain
        text/css
        application/javascript
        application/json
        application/xml
        image/svg+xml;
}

성능 튜닝 팁

선택한 알고리즘에 관계없이 최대 효과를 위해 다음 모범 사례를 준수하세요.

1. 실제 응답 확인

구성 파일에 gzip on; 또는 brotli on;이 있다고 해서 압축이 작동한다고 가정하지 마세요. 실제 응답을 확인하세요.

curl -I -H 'Accept-Encoding: br,gzip' https://example.com/app.js
curl -I -H 'Accept-Encoding: gzip' https://example.com/app.js

Content-Encoding: br 또는 Content-Encoding: gzip을 찾으세요. 또한 CDN이나 공유 프록시에 의해 캐시될 수 있는 응답에 Vary: Accept-Encoding을 유지하여 압축 및 비압축 변형이 혼합되지 않도록 하세요.

2. 과도한 압축 피하기

서버가 심각하게 활용도가 낮지 않은 한 gzip_comp_level 또는 brotli_comp_level을 너무 높게(예: 9 또는 11) 설정하지 마세요. 파일 크기 감소의 미미한 이득은 계산에 필요한 추가 CPU 주기를 거의 정당화하지 못합니다.

3. 사전 압축 파일 캐싱

Brotli의 경우 brotli_static on;을 사용하고 정적 자산을 사전 압축하는 것이 가장 큰 성능 향상입니다. 이렇게 하면 CPU 부하가 요청 시간에서 배포 시간으로 이동합니다.

4. 구성 테스트

Nginx 구성을 수정한 후에는 항상 다시 로드하기 전에 구문을 테스트하세요.

sudo nginx -t

성공하면 Nginx를 다시 로드하여 변경 사항을 적용하세요.

sudo systemctl reload nginx

브라우저 개발자 도구나 성능 테스트 서비스를 사용하여 응답이 Content-Encoding: gzip 또는 Content-Encoding: br로 제공되는지 확인할 수도 있습니다.

이를 적용하는 실용적인 방법

사이트에 압축이 전혀 없는 경우 Gzip부터 시작하세요. 대부분의 Nginx 패키지에 내장되어 있으며 빠른 기준선을 제공합니다. 그런 다음 모듈 지원을 확인하고 배포 중에 정적 자산에 대한 .br 파일을 생성할 방법이 있으면 Brotli를 추가하세요.

React, Vue 또는 정적 문서 사이트의 경우 최상의 설정은 일반적으로 빌드된 자산에 대해 사전 압축된 .br.gz 파일, HTML 및 API 응답에 대한 적당한 동적 압축, 그리고 Accept-Encoding을 존중하는 CDN 구성입니다. CPU 제한에 가깝게 실행되는 소규모 API의 경우 보수적인 Gzip 수준이 더 나은 첫 번째 단계일 수 있습니다.

이점은 단순히 더 작은 파일만이 아닙니다. 좋은 압축은 대역폭을 낮게 유지하고, 느린 클라이언트 연결을 지원하며, 애플리케이션 코드를 변경하지 않고 불필요한 전송 시간을 제거합니다. 주요 규율은 헤더를 테스트하고, 이미 압축된 미디어를 압축하지 않으며, 트래픽 급증 중에도 서버가 숨을 쉴 수 있도록 압축 수준을 적당히 유지하는 것입니다.