CloudFlareの提案するHTTP/2の圧縮辞書拡張

IETFのHTTPbis wgでCloudFlareの方より「Compression Dictionaries for HTTP/2」(URL)という仕様が提案されている。


これは、Content-Encodingヘッダで指定される圧縮アルゴリズム向けの初期ウィンドウに使用される辞書データを事前に送る拡張を定義する。


CloudFlareではすでに検証されており、通常のDeflate(zlib compression level 8))より最大1.50倍、平均で1.10倍縮小できたとしている。

背景

  • CSS/JS/HTMLといったアセットは、Content-Encodingを使用しDeflateやBrotliで圧縮される
  • HTTP/2以前は、リクエスト数を少なくするためにインライン化などを行っていた
  • 圧縮アルゴリズムは、後方一致するほど圧縮率が上がる
  • HTTP/2で小さいファイルを多重化して送ることが推奨化されており、圧縮率が上がらない。

拡張フレーム

この仕様では、2つの拡張フレームを定義している。大雑把に言うと辞書を宣言するフレームと、辞書を適応するフレームである。

SET_DICTIONARYフレーム
   +-------------+-------------+
   | Dict ID (8) |   Size (8)  |
   +-------------+-------------+
  • Dict ID: 辞書のためのスロットを指定する値
  • Size: 辞書のサイズ
USE_DICTIONARY
   +-------------+
   | Dict ID (8) |
   +-------------+

Dict ID: SET_DICTIONARYでセットされた辞書のスロットを指定する

動作

サーバ側

サーバは、最初のDATAフレームを送る前にいかなるストリーム上でSET_DICTIONARYフレームを送信できます。サーバは最初の2^Sizeの圧縮されてないオクテットを後続のストリームのためのCompression Dictionaryとして使用します。


サーバはストリームでDATAフレームを送信する前にUSE_DICTIONARYフレームを送ることで、Compression Dictionaryでストリームを圧縮できます。

クライアント側

クライアントはSET_DICTIONARYフレームを受信するとそのサイズ分だけ辞書のためにスロットを予約します。
そのストリームでDATAを受信したあと、最初の2^Sizeオクテットを辞書として保存します。


USE_DICTIONARYを受け取った際、クライアントはDATAの複合に指定された辞書を使用します。