ゆるテックノート

圧縮と転送(gzip/br/zstd)

配布やAPIで「圧縮をかける/かけない」を判断しやすくするためのメモです。HTTP仕様(RFC 9110 8.4)に沿ってAccept-Encoding/Content-Encodingの扱いも整理しました。

圧縮の基本

HTTPでの圧縮は「クライアントが受け入れ可能な方式」をAccept-Encodingで申告し、サーバーがContent-Encodingで実際に使った方式を示します。

主なヘッダー

ヘッダー 役割
Accept-Encoding クライアントが受け入れられる圧縮方式(例: gzip, br, zstd, identity)。q値で優先度指定。
Content-Encoding レスポンスで実際に使った圧縮方式。複数付ける場合は適用順。
Vary: Accept-Encoding 圧縮有無でレスポンスが変わるため必須。CDN/ブラウザキャッシュに別物として扱わせる。

方式別の特徴

代表的な3方式の圧縮率とCPU負荷の目安です。圧縮レベルは実装依存ですが、ここではよく使われる設定の感覚値を示します。

圧縮効率の目安(テキスト中心)

方式 圧縮率の目安 速度/負荷の傾向 よく使う場面
gzip (level 6〜7) 約30〜70%削減 中。互換性が高くデフォルトで安全。 HTML/JS/CSS、API JSON、ログ転送。
brotli (br, level 5〜6) gzipより+5〜20%程度良い 高め(gzipよりCPU重い)。低レベルならそこそこ速い。 Web配信でサイズを極力減らしたい静的アセット。
zstd (level 3〜5) gzip同等〜やや良い 低〜中。高速圧縮/伸張が得意。 API応答、ログ/トレース転送、バッチ配布。

選び方のヒント

  • ブラウザ互換性を最優先: gzipは最も安全。brはHTTP/2以降のブラウザで広く利用可、zstdは現時点でブラウザ対応が限定的。
  • CPUコストを抑えたいAPI: zstd低レベル(例: 3〜5)やgzipデフォルトを選ぶ。
  • 静的ファイルは事前圧縮: ビルド時にbr/gzipを生成し、Nginx等で拡張子マッピング配信。

設定ポイント

プロキシやCDNが絡むと圧縮ミスがユーザーに届きやすいため、ヘッダーと適用範囲を明確にします。

チェックリスト

  • バイナリ(画像/動画/ZIPなど)は再圧縮しない。Content-Typeでフィルタする。
  • Content-Encodingが付いたらVary: Accept-Encodingも必ず付ける。
  • Range要求に対応する場合、圧縮後のバイトレンジになる点に注意(大きなファイルは圧縮レスのほうが扱いやすい)。
  • TLS終端やCDNが再圧縮する設定になっていないか確認。二重圧縮は不具合の元。
  • プリロード/プリフェッチで同一リソースを複数エンコーディングで配る場合、キャッシュキーにエンコーディングが含まれるか確認する。

まとめ

互換性ならgzip、サイズ重視ならbr、速度重視ならzstdが目安。Accept-Encoding/Content-EncodingとVaryを正しく扱い、圧縮対象をテキスト中心に絞るとトラブルが減ります。