Content-Encoding - HTTP圧縮(gzip / br / zstd)

入門 | 10分 で読める | 2026.05.02

公式ドキュメント

Content-Encodingとは

Content-Encodingは、representationへ適用されたcontent codingを示すrepresentation headerです。requestとresponseの両方に現れ得ますが、Web配信では主に、HTML、CSS、JavaScript、JSONなどを圧縮したresponseで目にします。

圧縮率は、内容、ファイルサイズ、方式、圧縮レベルによって変わります。「常にBrotliが最小」「必ず何%減る」とは決められないため、実際のコンテンツで測ることが重要です。

圧縮方式を決める流れ

ClientがAccept-Encodingで受入可能な圧縮方式を送り、serverが選んだ方式をContent-Encodingに示して圧縮bodyを返し、clientがdecodeする図

クライアントとサーバーは、次のように圧縮方式を交渉します。

1. クライアントが候補を送る

クライアントはAccept-Encodingで、デコードできる方式を伝えます。

GET /app.js HTTP/1.1
Host: example.com
Accept-Encoding: gzip, br, zstd

実際の候補は、ブラウザ、OS、接続方法によって異なります。サーバーは一覧にない方式を一方的に選べません。

2. サーバーが1つ選ぶ

サーバーは、対応状況、コンテンツ、CPU負荷、事前圧縮ファイルの有無などから方式を選びます。

HTTP/1.1 200 OK
Content-Type: application/javascript
Content-Encoding: br
Vary: Accept-Encoding

Content-Encoding: brは、本文がBrotliで圧縮されていることを示します。ブラウザは本文を復元してからJavaScriptとして扱います。

適切な方式がない場合は、圧縮しないidentityで返せます。Accept-Encodingの品質値やidentity;q=0などの条件によっては、サーバーが受け入れ可能な表現を返せないこともあります。

3. キャッシュを分ける

同じURLでも、クライアントによってgzipbr、未圧縮の応答があり得ます。そのため、共有キャッシュへ次を伝えます。

Vary: Accept-Encoding

これがないと、あるクライアント向けの圧縮応答を、対応していないクライアントへ返す事故につながります。CDNやフレームワークが自動設定する場合も、実際の応答で確認します。

gzip・Brotli・Zstandardの選び方

方式特徴検討しやすい場面
gzip長く使われ、幅広い環境で扱いやすい互換性を重視する動的・静的コンテンツ
brテキストで良い圧縮結果を得られる場合があるビルド時に事前圧縮できる静的ファイル
zstd圧縮・展開速度と圧縮率のバランスを調整しやすい対象クライアント、CDN、サーバーが対応する環境

ZstandardのHTTPコンテンツコーディングはRFC 8878で定義されています。ただし、規格があることと、利用中の全ブラウザ・CDN・Webサーバー・監視ツールが同じように対応することは別です。導入時点の対象環境で確認し、非対応クライアントにはgzipや未圧縮で返します。

deflateもHTTPのコンテンツコーディングとして定義されていますが、新しい構成で積極的に選ぶ理由は多くありません。既存システムとの互換性が必要な場合に、実装の挙動を確認して扱います。

圧縮レベルは高ければよいわけではない

多くの圧縮方式には、速度とサイズを調整するレベルがあります。高いレベルは小さくなる可能性がありますが、圧縮時間とCPU使用量も増えます。

静的ファイル

ビルド時に一度だけ圧縮し、.gz.brを配信できるため、比較的時間をかけられます。ただし、最高レベルの追加時間に見合うサイズ差があるか測ります。

動的レスポンス

リクエストごとに圧縮するJSONやHTMLでは、圧縮処理が応答時間やサーバー容量へ影響します。低めのレベル、一定サイズ以上だけ圧縮、CDNでの圧縮などを比較します。

比較するときは、次を同じ条件で測ります。

  • 元データと圧縮後のバイト数
  • 圧縮と展開にかかる時間
  • CPUとメモリ使用量
  • キャッシュヒット率
  • 対象ブラウザと中継機器での成功率

圧縮しないほうがよい内容

次の内容は、圧縮効果が小さいか、別の問題を生む場合があります。

  • JPEG、WebP、AVIF、MP4、ZIPなど、すでに圧縮されているデータ
  • ヘッダーを含めた追加処理に対して非常に小さい本文
  • CPU負荷が高く、転送量削減より応答遅延が問題になるレスポンス
  • 秘密情報と攻撃者が操作できる文字列を同じ応答に含む内容

最後のケースでは、圧縮後サイズの変化から秘密を推測するBREACHのような攻撃を考慮します。CSRF対策、秘密と入力の分離、該当応答の圧縮無効化などを、システムの脅威に合わせて検討します。

Content-Typeとの違い

Content-Typeは、復元後の本文が何であるかを示します。Content-Encodingは、その本文へどの変換を適用したかを示します。

Content-Type: application/json
Content-Encoding: gzip

この場合、転送された本文をgzipで展開するとJSONになります。

Content-Lengthが付く場合、その値は通常、転送される符号化後の本文サイズです。展開後のサイズではありません。

実際の応答を確認する

curlで、サーバーがどの方式を選ぶか確認できます。

curl --compressed -I https://example.com/app.js

特定の候補を送って比較する場合は、次のようにします。

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

確認する主なヘッダーは次のとおりです。

Content-Encoding: br
Vary: Accept-Encoding
Content-Length: 18420

ブラウザのDevToolsでは、NetworkパネルでContent-Encodingと、転送サイズ・リソースサイズを確認します。Service Worker、ブラウザキャッシュ、CDNキャッシュが結果へ影響するため、キャッシュ条件をそろえて比較します。

まとめ

  • Accept-Encodingでクライアントが候補を示し、サーバーが1つ選ぶ
  • 選んだ方式をContent-Encodingで示す
  • 圧縮方式ごとに応答が変わる場合はVary: Accept-Encodingが重要
  • gzip、Brotli、Zstandardに絶対的な優劣はなく、内容と運用条件で選ぶ
  • Zstandardは対象ブラウザ、CDN、サーバーの対応を導入時に確認する
  • すでに圧縮済みのデータや小さな本文は、圧縮しないほうがよい場合がある
  • 圧縮率だけでなく、CPU、応答時間、キャッシュも含めて測る

参考リソース

← 一覧に戻る
PR
PR
PR
PR