HTTP圧縮


HTTP圧縮とはHTTP通信を自動的に圧縮する(WebサーバがHTTP通信を圧縮し、ブラウザでその圧縮を解く)ことです。

メリット

通信量を減らし全体的なスループットをあげることができます。モバイルのような帯域の限られている環境では特に有効です。

デメリット

圧縮および伸張にCPUパワーを必要とします。

  • サーバ:HTTP圧縮を有効にすると配信能力が低下します。
  • クライアント:スマートフォンの普及とともにCPU負荷および消費電力の増加は大きな問題ではなくなっています

プロトコル

  • クライアント(ブラウザ)リクエスト
    • 以下のようにAccept-Encodingを付けてGETリクエストを送信します。
      • GET /test.html HTTP/1.1
        Host: example.com
        Accept-Encoding: gzip, deflate
  • サーバレスポンス
    • 以下のようにContent-Encodingが付けられたレスポンスが返され、httpペイロードは指定された方法で圧縮されます。
      • HTTP/1.1 200 OK
        Date: mon, 23 Mar 2016 22:38:34 GMT
        Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
        Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
        Accept-Ranges: bytes
        Content-Length: 438
        Connection: close
        Content-Type: text/html; charset=UTF-8
        Content-Encoding: gzip
        gzip圧縮されたペイロード

圧縮方式

Accept-encoding、Content-encodingで指定できる圧縮方法には以下のようなものがあります(抜粋です)。

  • 標準
    • identity
      • 変換していないことの明記
    • deflate
      • アルゴリズム:LZ77、ハフマン符号
      • フォーマット:zlib
    • gzip
      • アルゴリズム:LZ77、ハフマン符号
      • フォーマット:Gnu zip
  • 非標準
    • bzip2
      • 特徴:deflateやgzipよりも圧縮率が高い
      • アルゴリズム:Burrows-Wheeler transform (BWT) aka ブロックソート
      • フォーマット:bzip2
    • brotli
      • 特徴:Googleが開発した最新(2015年発表)アルゴリズムを使用、HTTPSのみをサポート(HTTPSを推進するというポリティカルな理由)
      • アルゴリズム:LZ77、ハフマン符号、2nd order context modeling
      • フォーマット:brotli

Web(オリジン)サーバにおけるサポート

  • apache
    • mod_deflateによりサポートされます
      • 圧縮はリクエスト毎に行われます
  • nginx
    • gzip onの設定により有効化されます

Cacheサーバ(CDN)におけるサポート

Cacheサーバ(CDN)は、以下の2種類のモードでHTTP圧縮をサポートします

オリジン依存モード

これは、RFCに規定されたWeb Cacheの基本動作で、多くのCDNがサポートしている可能性があります。

基本的な動作として、Cacheサーバは圧縮を行わず、複数のコンテンツ(たとえば、非圧縮html、gzip圧縮html、deflate圧縮html)を保持します。そして以下のようなフローで保存したコンテンツをクライアントに送信します:

  • オリジンサーバが送信した圧縮済みHTTPペイロードをそのまま保存する
    • Encoding別にキャッシュを生成する
  • クライアントからの要求(Accept-Encoding)にあわせたキャッシュをクライアントに送信する

このEncodingに合わせたキャッシュオブジェクトの識別は、次のようにVaryヘッダ(RFCで規定されたCache動作指定)をオリジンサーバが付与することで実現できます。また、apacheのmod_deflateは自動的にVaryを付与します:

  • HTTP/1.1 200 OK
    Date: mon, 23 Mar 2016 22:38:34 GMT
    Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
    Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
    Accept-Ranges: bytes
    Content-Length: 438
    Connection: close
    Content-Type: text/html; charset=UTF-8
    Content-Encoding: gzip
    Vary: Accept-Encoding

注意点

Cacheサーバは(Content-Encoding別にオブジェクトをキャッシュしているのではなく)、Accpet-Encoding別にオブジェクトをキャッシュしています。つまり、クライアントが”Accept-Encoding: gzip, deflate”を送信したときにサーバが返したencodingのオブジェクトがキャッシュされ、それ以降の”Accept-Encoding: gzip, deflate”に対して使用されます。そして、”Accept-Encoding: gzip”のように単独でencodingが指定されたリクエストに対しては、別のオブジェクトが生成されます。

CDNでは、無条件にVary動作を許すとひとつのURLに対して複数のオブジェクト(数十程度:Accept-Encodingの組み合わせ分)が生成される可能性があるため、何らかの制限をかけている場合があります。たとえば、「gzip(もっとも多くの場合に使用されてている)のみを許し、それ以外は無視する」というような制限がかかっている場合があります。

Cache上圧縮モード

オリジンサーバでは圧縮を行わずCacheサーバで圧縮を行います。この機能は各CDNに依存した実装になります。