Nginx Gzip圧縮:ウェブサイトの読み込み速度を向上させる

Nginx Gzip圧縮を有効にしてテキストベースのレスポンスを縮小し、ページの読み込み速度を向上させる方法を解説。安全な設定、対象MIMEタイプ、テスト方法、CDN考慮事項をカバー。

Nginx Gzip圧縮:ウェブサイトの読み込み速度を向上させる

Nginx Gzip圧縮は、テキストベースのレスポンスをネットワーク経由で送信する前に縮小することで、ウェブサイトの読み込みを高速化します。ページにHTML、CSS、JavaScript、JSON、XML、SVGファイルが含まれている場合、圧縮により転送サイズを削減し、ブラウザでの表示を変えることなくパフォーマンスを向上させます。

目標はシンプルです:送信バイト数を減らし、待機時間を短縮し、帯域幅をより有効活用すること。ほとんどの本番サイトでは、Gzipは安全に有効化できる最も簡単なNginxパフォーマンス向上策の1つです。

NginxでのGzip圧縮の仕組み

Gzip圧縮は、Nginxがレスポンスを選択した後、クライアントに送信する前に実行されます。ブラウザはAccept-Encodingリクエストヘッダーでサポートを通知します。Gzipが有効で、レスポンスタイプが設定と一致する場合、Nginxはボディを圧縮し、Content-Encoding: gzipと共に送信します。

これはテキスト形式に最適です。なぜなら、それらには繰り返しパターンが含まれているからです。HTMLテンプレート、CSSクラス名、JavaScript識別子、JSONキーは非常に効率的に圧縮されることが多いです。画像、動画、PDF、アーカイブは通常すでに圧縮されているため、それらをgzipしようとすると、ファイルサイズをあまり減らさずにCPUを浪費する可能性があります。

基本的な設定は通常httpブロックに記述され、すべてのサーバーブロックに適用されます:

gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_vary on;
gzip_proxied any;
gzip_types
    text/plain
    text/css
    text/xml
    application/json
    application/javascript
    application/xml
    application/rss+xml
    image/svg+xml;

gzip onディレクティブは圧縮を有効にします。gzip_typesは、デフォルトのtext/htmlに加えてNginxが圧縮するMIMEタイプを指定します。gzip_min_lengthは、Gzipヘッダーのオーバーヘッドがメリットを打ち消す可能性がある小さなレスポンスにCPUを費やすのを防ぎます。

gzip_vary onVary: Accept-Encodingヘッダーを追加します。これはサイトがCDNや共有キャッシュの背後にある場合に重要です。キャッシュは、圧縮されたバージョンと圧縮されていないバージョンが同じURLの異なるバリアントであることを認識する必要があるからです。

より広範なNginxパフォーマンスベースラインについては、Nginxパフォーマンスチューニングも確認することをお勧めします。

よくある注意点:NginxはGzipが有効な場合、常にtext/htmlを圧縮するため、text/htmlgzip_typesに含める必要はありません。もし追加した場合、NginxはMIMEタイプが重複していると警告する可能性があります。この警告は無害ですが、設定がクリーンアップされずにコピーされたことを示しています。

安全な圧縮設定の選択

Nginx Gzip圧縮で最大の間違いは、圧縮レベルを音量調節ノブのように扱うことです。高いほど常に良いわけではありません。Gzipレベルは通常1から9の範囲です。レベル1は最速ですが圧縮率は低くなります。レベル9はより圧縮しますが、CPUコストが顕著に増加する可能性があります。

多くのウェブサイトでは、gzip_comp_level 456が実用的な範囲です。サーバーに過度な負荷をかけずに強力な圧縮を提供します。Nginxサーバーが高トラフィックを処理する場合や小規模インスタンスで動作する場合は、レベル9に直接ジャンプしないでください。

適切なデフォルトは次のようになります:

  • バランスの取れた設定にはgzip_comp_level 5を使用。
  • 小さなレスポンスが圧縮をスキップするようにgzip_min_length 1024を使用。
  • テキストベースのアセットを圧縮し、すでに圧縮されたメディアは圧縮しない。
  • キャッシュやCDNが関与する場合はgzip_vary onを維持。
  • 圧縮有効化後にCPU使用率をテスト。

よくあるシナリオ:多くのCSS、JavaScript、HTMLページを持つドキュメントサイトを運営しているとします。Gzip前は、ページが650 KBのテキストアセットを読み込んでいました。圧縮を有効にすると、転送サイズが大幅に減少し、ブラウザは解凍後も同じファイルを受け取ります。低速接続のユーザーが最も改善を実感します。

すべてのサイトで効果が均等とは限りません。JPEG画像が大半を占めるページはGzipで大きく改善しません。大きなJSONレスポンスを送信するダッシュボードは大幅に改善する可能性があります。

APIの場合は、より慎重に検討してください。{"ok":true}のような小さなJSONレスポンスを圧縮するのは通常無意味です。300 KBの検索結果やレポートペイロードを圧縮するのは価値があります。APIがプライベートデータを返し、同じレスポンスにユーザー制御の入力を反映する場合は、アプリケーションチームと圧縮リスクについて話し合ってから、すべての場所で有効にしてください。これは「APIを決して圧縮しない」という意味ではありません。圧縮は、キャッシュ、クッキー、レスポンスヘッダーと同じレビューバケットに属するということです。

Gzipが機能しているかテストする方法

Nginx設定を変更した後、リロード前に構文をテストします:

nginx -t

次に、サービス管理ツールやデプロイプロセスを通じてNginxをリロードします。これは設定変更であり、完全なバイナリ再起動ではないため、通常リロードで十分です。

curlでレスポンスを確認できます:

curl -I -H "Accept-Encoding: gzip" https://example.com/app.css

次のヘッダーを探します:

Content-Encoding: gzip

また、次のヘッダーも確認します:

Vary: Accept-Encoding

Content-Encoding: gzipが表示されない場合は、レスポンスのMIMEタイプを確認してください。例えば、text/plainとして提供されるJavaScriptファイルは、text/plainが含まれていれば圧縮される可能性がありますが、カスタムAPIレスポンスで通常とは異なるコンテンツタイプを使用している場合、gzip_typesリストと一致しない可能性があります。

ブラウザの開発者ツールも役立ちます。ネットワークタブを開き、ページをリロードして、レスポンスヘッダーと転送サイズを確認します。圧縮可能なファイルの場合、転送サイズは非圧縮のリソースサイズよりも小さくなるはずです。

CDNも使用している場合、CDNが独自の圧縮を実行する可能性があることを覚えておいてください。その場合、Nginxがブラウザが受け取るものを決定する最終層ではないかもしれません。可能であれば、直接のオリジンアクセスと公開CDN URLの両方をテストしてください。

直接のオリジンレスポンスが圧縮されているがCDNレスポンスが圧縮されていない場合、CDNの圧縮設定とキャッシュキーの動作を確認してください。CDNレスポンスが圧縮されているがオリジンが圧縮されていない場合、それは問題ないかもしれません。多くのチームは、オリジン設定をシンプルに保ちながら、CDNに公開静的圧縮を任せています。

Gzipに注意すべき場合

Gzipはほとんどの静的および動的コンテンツに対して安全ですが、注意深くテストすべきケースがあります。

すでに圧縮されているファイルは圧縮しないでください。一般的な例:

  • .jpg.jpeg.png.webp
  • .mp4.mov、その他の動画形式
  • .zip.gz.tar.gz、パッケージアーカイブ
  • ほとんどのフォントファイル(形式と配信パスによる)

また、CPU使用率にも注意してください。圧縮は無料ではありません。サーバーがすでにCPU制限近くで動作している場合、積極的な圧縮を有効にすると、負荷時の応答時間が悪化する可能性があります。適度な設定から始め、トラフィック、レイテンシ、CPUを監視してください。

セキュリティに敏感なアプリケーションでは、攻撃者が制御する入力の隣にある圧縮レスポンスで秘密を公開しないようにする必要もあります。これはより専門的なリスクですが、トークンやプライベートデータを含むページにユーザー入力を反映するアプリでは知っておく価値があります。

静的アセットの場合、別のオプションとして、ビルドパイプライン中にファイルを事前圧縮し、ディスクから.gzバージョンを提供することです。これにより、特に大規模なJavaScriptバンドルでランタイムCPUを削減できます。動的APIレスポンスは、圧縮したい場合は依然としてランタイム圧縮が必要です。

事前圧縮ファイルを提供する場合は、gzip_static on;を有効にし、.gzファイルが非圧縮ファイルとまったく同じアセットバージョンから生成されていることを確認してください。新しいapp.jsの隣に古いapp.js.gzがあると、厄介なバグが発生します:Gzipを要求するクライアントだけが古いコードを見ることになります。

gzip_static on;

このディレクティブはビルドアーティファクトに便利であり、動的なアップストリームレスポンスには適していません。アプリサーバーからプロキシされた動的レスポンスの場合、アップストリームがすでに圧縮されたボディを送信しない限り、Nginxは依然としてランタイム圧縮が必要です。

ヘルプが必要な場合

Gzipの有効化により、CPU使用率の上昇、CDNの一貫性のない動作、古いクライアントでのレスポンスの破損が発生した場合は、経験豊富なNginx管理者またはDevOpsエンジニアに相談してください。また、圧縮設定が複数のインクルード設定ファイルに混在しており、どのブロックが実際にアクティブかわからない場合も助けを求めてください。

シンプルなウェブサイトの場合、Gzipは数分で有効化できます。高トラフィックのアプリケーションの場合は、他のパフォーマンス変更と同様に扱ってください:テストし、段階的に展開し、結果を監視してください。

Nginx Gzip圧縮は、テキスト主体のサイトやAPIの読み込み速度を向上させる実用的な方法です。MIMEタイプを適切に絞り込み、適度な圧縮レベルを選択し、リロード後にヘッダーを確認してください。設定が機能すれば、アプリケーションコードを変更することなく、ユーザーはより小さなレスポンスを受け取ることができます。