ゆるテックノート

圧縮と転送(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 Accept-Encodingを基に表現を選ぶ場合、キャッシュが対応する要求を区別するために使う。Content-Encodingがあるという理由だけで常に必須ではない。

方式別の特徴

圧縮率や処理時間は内容・実装・レベルで変わります。固定の削減率では判断せず、実データの転送量・圧縮時間・展開時間を測ります。

方式ごとの確認点

方式 確認すること
gzip 受信側の対応と、圧縮レベルによるサイズ・処理時間の変化。
brotli (br) 静的配信では事前圧縮も選択肢。サイズと生成時間を実測する。
zstd クライアント・サーバー双方の対応を確認し、実装とレベルごとに測定する。

選び方のヒント

  • 実際のAccept-Encodingに対応する方式を選ぶ。brの利用はHTTP/2以降に限られず、HTTPのバージョンと圧縮方式は別の選択。ブラウザや配信環境の対応を確認する。
  • 動的APIでは、転送量の削減と圧縮による応答遅延を両方測る。圧縮レベルの数字は方式をまたいだ性能比較には使えない。
  • 静的ファイルは事前圧縮: ビルド時にbr/gzipを生成し、Nginx等で拡張子マッピング配信。

設定ポイント

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

チェックリスト

  • JPEG・PNG・ZIPなど既に圧縮されたデータは追加圧縮の効果が小さいことが多い。バイナリかどうかだけで決めず、サイズと処理時間を測る。
  • Accept-Encodingで表現を切り替えるキャッシュ可能な応答には、通常Vary: Accept-Encodingを付ける。非圧縮版も含め、同じ選択規則でキャッシュが区別できるようにする。
  • Range要求に対応する場合、圧縮後のバイトレンジになる点に注意(大きなファイルは圧縮レスのほうが扱いやすい)。
  • TLS終端やCDNが再圧縮する設定になっていないか確認。二重圧縮は不具合の元。
  • プリロード/プリフェッチで同一リソースを複数エンコーディングで配る場合、キャッシュキーにエンコーディングが含まれるか確認する。

まとめ

相手が受け入れる方式から実測で選び、実際の本文に合うContent-Encodingを返します。圧縮の有無で表現を切り替える場合はVaryとキャッシュの動作も確認します。

仕様と関連する説明

RFC 9110 Accept-Encoding / Vary / Brotli / Zstandard / HTTPキャッシュ