Nginx圧縮の極意:WebパフォーマンスにおけるGzip vs. Brotli

GzipとBrotliアルゴリズムを比較しながら、Nginxのコンテンツ圧縮をマスターします。両方を有効にするための実践的な設定ディレクティブを理解し、パフォーマンスのトレードオフを把握し、静的Brotliファイルを使用して帯域幅を大幅に削減し、Webサーバー上のコンテンツ配信を高速化するベストプラクティスを発見します。

Nginx圧縮の極意:WebパフォーマンスにおけるGzip vs. Brotli

Nginxの圧縮は、ネットワークパネルを見るまでは小さな変更に感じられます。CSSファイル、JavaScriptバンドル、HTMLページ、JSON APIレスポンス、SVGは、ワイヤー上ではるかに小さなレスポンスとして転送され、ブラウザで同じコンテンツに展開されることがよくあります。

実際の選択は、通常「GzipかBrotliかを永遠に選ぶ」というものではありません。ほとんどの本番環境では両方を使用します。Brotliはそれを要求するブラウザ向けに、Gzipはフォールバックとして、そしてビルドパイプラインで事前に作成できる静的ファイルには事前圧縮を使用します。ただし、詳細が重要です。コピーされた圧縮ブロックはCPUを浪費したり、重要なMIMEタイプをスキップしたり、Brotliモジュールが実際にインストールされていないために静かに失敗したりする可能性があります。

NginxにおけるWeb圧縮の理解

圧縮は、データ(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またはインクルードされた設定ファイル)のhttpserver、または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_levelbrotli_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レベルが最初のより良い動きかもしれません。

利点は、ファイルが小さくなることだけではありません。適切な圧縮により、帯域幅を低く抑え、遅いクライアント接続を支援し、アプリケーションコードを変更せずに不要な転送時間を排除します。主な規律は、ヘッダーをテストし、すでに圧縮されているメディアの圧縮を避け、トラフィックの急増中でもサーバーが呼吸できるように圧縮レベルを適切に保つことです。