brotliのwindowサイズとgzipとのサイズ比較(ベンチマーク)

[前回はmod_brotliのインストール方法](https://qiita.com/takeshi_nozawa/items/14880f8f7a4ac8aa91b7)についてご紹介しましたので、今日はベンチマークをいくつかやってみたいと思います。

下記は私が担当しているサイトのとあるページをbrotliとdeflate(gzip)で圧縮した場合の比較になります。
brotliの圧縮レベルはデフォルトの5。gzipとほとんど差がないですね。

| 指標 | brotli | gzip | 差異(br - gzip) | 圧縮後のサイズ比( br / gzip) |
|:--|--:|--:|:--|:--|
| ページの合計サイズ(MB)※1 | 1.2 | 1.2 | 0 | 100% |
| ドキュメントのサイズ(KB)※2 | 159 | 160 | -1 | 99% |
| CSS(KB) | 28.5 | 30 | -1.5 | 95% |
| JS(KB) | 103 | 109 | -6 | 94% |

- ※1 画像も含めた１ページあたりの合計サイズ
- ※2 text/htmlのドキュメントファイルのサイズ

## ベンチマーク

悔しいので詳細なベンチマークを継続してみました。

### どのwindowサイズが最適なのか？

brotliではWindowサイズを変更できるということで、それぞれ22(brotliコマンドのデフォルト値)、18(apacheのmod_brotliのデフォルト値）、
0(brotliのヘルプによるところの"optimal"な値とのこと)で試してみました。セル内の数字は圧縮後のサイズです。
またオリジナル(CSS)のファイルサイズは166KB(169,632B)です。

| 圧縮レベル | w=22 | w=18 | w=0 |
|--:|:--|:--|:--|
| 1 | 39,290 | 39,290 | 71,182 |
| 2 | 33,696 | 33,696 | 46,755 |
| 3 | 32,544 | 32,544 | 45,984 |
| 4 | 31,295 | 31,295 | 42,102 |
| 5 | 28,776 | 28,776 | 38,823 |
| 6 | 28,190 | 28,190 | 38,806 |
| 7 | 27,790 | 27,790 | 38,781 |
| 8 | 27,580 | 27,580 | 38,781 |
| 9 | 27,401 | 27,401 | 38,751 |
| 10 | 25,585 | 25,585 | 34,444 |
| 11 | 25,202 | 25,202 | 33,382 |

![図1.png](https://qiita-image-store.s3.amazonaws.com/0/237077/af0ddbb1-5891-c916-e8c0-cbb45f36a333.png)

ご覧の通りwindowサイズで比較すると、0(optimal)よりも何かしたら数字を指定したほうが良いことがわかります。また、brotliのデフォルト値の22とmod_brotliのデフォルト値の18では結果は変わりません。「windowサイズが大きいほど必要とするメモリも大きくなる」とのことから、今回の例においてwindowサイズは18で問題はなさそうです。

JSファイルでも試してみました。

CSSと同様にwindowサイズを0, 18 ,22で比較してみます。こちらのオリジナルのサイズは374K(382,213B)で、先程のCSSの2倍強くらいのサイズです。

| 圧縮レベル | w=0 | w=18 | w=22 |
|--:|:--|:--|:--|
| 1 | 209,512 | 133,676 | 133,676 |
| 2 | 155,826 | 116,946 | 116,967 |
| 3 | 153,865 | 115,203 | 115,214 |
| 4 | 145,587 | 111,955 | 111,917 |
| 5 | 135,388 | 105,112 | 105,110 |
| 6 | 135,380 | 104,095 | 104,080 |
| 7 | 135,343 | 103,371 | 103,376 |
| 8 | 135,343 | 103,162 | 103,109 |
| 9 | 135,224 | 102,887 | 102,853 |
| 10 | 124,156 | 97,205 | 97,361 |
| 11 | 120,997 | 96,006 | 96,002 |

![図3.png](https://qiita-image-store.s3.amazonaws.com/0/237077/1686df16-30fe-59b8-7e17-41987fcf352a.png)

結果はCSSでの比較と同様でwindowサイズの18と22ではほとんど変化がありません。が、おすすめであるはずのoptimal(w=0)では圧縮率が高くないです。ウィンドウサイズについてはCSSとJSで大きな違いはないようです。

次にbrotliのwindowサイズ18の圧縮結果とgzipの圧縮結果を比較してみた。

### brotliとgzipの比較

| 圧縮レベル | brotli | gzip | 差異(br - gzip) | %(br / gzip) |
|--:|:--|:--|:--|:--|
| 1 | 39,290 | 39,202 | 88 | 100% |
| 2 | 33,696 | 37,198 | -3,502 | 91% |
| 3 | 32,544 | 35,783 | -3,239 | 91% |
| 4 | 31,295 | 32,623 | -1,328 | 96% |
| 5 | 28,776 | 30,845 | -2,069 | 93% |
| 6 | 28,190 | 30,141 | -1,951 | 94% |
| 7 | 27,790 | 29,920 | -2,130 | 93% |
| 8 | 27,580 | 29,850 | -2,270 | 92% |
| 9 | 27,401 | 29,850 | -2,449 | 92% |
| 10| 25,585 | なし | | |
| 11| 25,202 | なし | | |

![図2.png](https://qiita-image-store.s3.amazonaws.com/0/237077/9c974705-2cdd-1a52-bd7d-f8779fcb1979.png)

ご覧の通り圧縮レベル1ではbrotoliよりもgzipのほうがサイズが小さくなっています。gzipは圧縮レベル5くらいから、圧縮レベルを上げてもサイズの変化が小さくなっています。一方brotliは11まで上げてもしっかり小さくなっていることがわかります。

今回は圧縮速度の測定はしていませんが、[goolgeのベンチマーク](http://www.gstatic.com/b/brotlidocs/brotli-2015-09-22.pdf)ではbrotliの11はメチャメチャ遅いことがわかります。
brで事前に固めてから配信するならともかく、on the flyで運用するならよっぽどCPUに余裕がないと難しそうです。

そしてJSでも比較をしてみたいと思います。こちらもbrotliのwindowサイズは18です。

| 圧縮レベル | brotli | gzip | %(br / gzip) | 差異(br - gzip) |
|--:|:--|:--|:--|:--|
| 1 | 133,676 | 131,896 | 101% | 1,780 |
| 2 | 116,946 | 126,647 | 92% | -9,701 |
| 3 | 115,203 | 123,249 | 93% | -8,046 |
| 4 | 111,955 | 115,629 | 97% | -3,674 |
| 5 | 105,112 | 111,960 | 94% | -6,848 |
| 6 | 104,095 | 110,539 | 94% | -6,444 |
| 7 | 103,371 | 110,298 | 94% | -6,927 |
| 8 | 103,162 | 110,217 | 94% | -7,055 |
| 9 | 102,887 | 110,217 | 93% | -7,330 |
| 10 | 97,205 | なし| | |
| 11 | 96,006 | なし| | |

こちらもCSSの比較と同様gzipでは圧縮レベル5以降のサイズに変化はありません。

![図5.png](https://qiita-image-store.s3.amazonaws.com/0/237077/c591b7ed-80d0-c0d3-c11e-d0a5e0210667.png)

## 結論と考察
- brotliはwindowサイズを調整すると圧縮後のサイズが変わる。今回のケース(CSSやJSをon the flyで配信する場合)ではapacheのmod_brotliである18がちょうど良い。
- とは言ってもgzipとの比較で言えば、やはり5%前後くらいしか変わらない。
- 事前に固めて配信できるなら、圧縮レベルを最高の11まで上げてやってもいいかも。
- 私の環境ではAmazon LinuxにyumでApacheをインストールしているのですが、mod_brotliはパッケージがないため、ソースからコンパイルしてインストールする必要がある。しかし、それに対するベネフィットがgzipに比べて数%しか変わらないとなると正直コストとあまり釣り合っていない。

## 参考(他の人のベンチマークなど)
- [googleが公開している他の圧縮アルゴリズムとのベンチマーク](https://qiita.com/isaoshimizu/items/28cdc0d08c1bdb7ab6c1)。brotliの圧縮レベルは1, 9, 11で比較されている。
- [「圧縮レベルは10にすべき」](https://ayesh.me/apache-brotli)という人もいる。
- http://hidekatsu-izuno.hatenablog.com/entry/2016/07/06/003803