Serving precompressed content with Nginx and Zopfli
Frederic Cambus March 11, 2013 [Nginx]Zopfli is a new compression algorithm which has recently been opensourced by Google. Being deflate compatible, it can create compressed files which can then be unpacked using zlib, and thus served to web browsers without any modifications on client side.
Zopfli is focused on output efficiency, not on runtime performance, making it impractical to use for doing on-the-fly compression. It shines at compressing static content, and I will show you how in this article using Ascii Codes website as an example.
We start by fetching and compiling Zopfli:
git clone https://code.google.com/p/zopfli/
cd zopfli
make
The available options are as follow:
Usage: zopfli [OPTION]... FILE
-h gives this help
-c write the result on standard output, instead of disk filename + '.gz'
-v verbose mode
--gzip output to gzip format (default)
--deflate output to deflate format instead of gzip
--zlib output to zlib format instead of gzip
--i5 less compression, but faster
--i10 less compression, but faster
--i15 default compression, 15 iterations
--i25 more compression, but slower
--i50 more compression, but slower
--i100 more compression, but slower
--i250 more compression, but slower
--i500 more compression, but slower
--i1000 more compression, but slower
We now compress the content (in our example, we want to pack HTML and CSS files):
zopfli *html *css
Alternatively, for maximum compression (1000 iterations):
zopfli --i1000 *html *css
Now, let's test the actual server configuration (Nginx + standard Gzip module):
curl https://www.ascii-codes.com --silent --header "Accept-Encoding: gzip,deflate" | wc -c
6124
The file size is 6,124 bytes: we are getting gzip content compressed on-the-fly.
We now modify our Nginx virtual host configuration to add the following directive:
gzip_static on;
Let's reload Nginx configuration:
nginx -s reload
And finally, we test again (Nginx + Gzip Precompression module):
curl https://www.ascii-codes.com --silent --header "Accept-Encoding: gzip,deflate" | wc -c
5621
As we can see, the file size is 5,621 bytes: it now serves the Zopfli precompressed content.
For reference, here is a comparison matrix of file sizes:
file name | original size | gzip -9 | zopfli | zopfli --i1000
------------|----------------|----------------|----------------|----------------
cp737.html | 36,567 bytes | 6,001 bytes | 5,499 bytes | 5,494 bytes
cp775.html | 36,040 bytes | 6,063 bytes | 5,540 bytes | 5,538 bytes
cp850.html | 36,047 bytes | 6,149 bytes | 5,651 bytes | 5,646 bytes
cp852.html | 36,120 bytes | 6,027 bytes | 5,493 bytes | 5,489 bytes
cp855.html | 36,388 bytes | 6,079 bytes | 5,581 bytes | 5,578 bytes
cp857.html | 35,861 bytes | 6,052 bytes | 5,575 bytes | 5,570 bytes
cp860.html | 36,506 bytes | 6,132 bytes | 5,657 bytes | 5,652 bytes
cp861.html | 37,185 bytes | 6,619 bytes | 6,268 bytes | 6,254 bytes
cp862.html | 36,078 bytes | 6,102 bytes | 5,580 bytes | 5,577 bytes
cp863.html | 36,421 bytes | 6,144 bytes | 5,677 bytes | 5,672 bytes
cp865.html | 36,347 bytes | 6,154 bytes | 5,661 bytes | 5,659 bytes
cp866.html | 36,595 bytes | 6,042 bytes | 5,541 bytes | 5,533 bytes
cp869.html | 36,014 bytes | 6,007 bytes | 5,479 bytes | 5,474 bytes
index.html | 36,035 bytes | 6,124 bytes | 5,631 bytes | 5,621 bytes
The results look pretty good indeed, and we can definitely achieve a non-negligible gain in file size using Zopfli instead of Gzip.
Every byte counts!