Last year, Google released a successor to the deflate
compression algorithm, Brotli. Chrome adopted it in version 51, and Firefox in version 44 (see Can I use…). That said, from the webserver side, nginx doesn’t support it natively, so Google provides the ngx_brotli
module, making it just a matter of compiling nginx.
Compiling a custom nginx build is not as daunting as it sounds. I described the process back in June, when I desired to preserve http/2 support so needed to switch to OpenSSL 1.0.2: http://ethitter.com/2016/06/nginx-openssl-1-0-2-http-2-alpn/.
Getting Brotli
First, we need the nginx module and the Brotli library checked out where we’ll build nginx. I use /usr/local/src
when building from sources, but the directory can be almost anything you’d like.
cd /usr/local/src git clone https://github.com/google/ngx_brotli.git cd ngx_brotli git submodule update --init --recursive
Now it’s time to compile an updated nginx.
Updating the nginx build configuration
Using the configuration from my earlier post, compiling nginx with Brotli is a matter of adding one additional flag to the ./configure
call:
--add-module=/usr/local/src/ngx_brotli
In my case, the full command is now:
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --with-openssl=/usr/local/src/openssl --user=www-data --group=www-data --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --add-module=/usr/local/src/ngx_brotli
Note that starting with 1.11.5, the --with-ipv6
flag was removed because the support is now added by default.
nginx can now be compiled and installed as noted in my previous post.
Enabling Brotli
Now that nginx supports Brotli, its nginx.conf
needs a small update to enable the new compression.
http { … brotli on; brotli_static on; brotli_types *; … }
Run nginx -t
to confirm the configuration and binary, then restart nginx to enable Brotli for all supported requests.
Two flavors of Brotli
In the above configuration, two types of Brotli were enabled: brotli
and brotli_static
. Given the name of the latter, one can probably figure out that brotli
enables the compression when each request is processed. brotli_static
allows pre-compressed versions of files to be served automatically when they’re present.
Creating the pre-compressed versions requires the Brotli command-line tool, which Scott Helme discusses in https://scotthelme.co.uk/brotli-compression/. Once .br
files are present, nginx will serve them instead of dynamically compressing the sources.
Since the bulk of my server’s requests are fronted by a CDN that doesn’t support Brotli (it falls back to gzip, fortunately), or are dynamic and served by WordPress, I only make use of on-the-fly compression. GitLab doesn’t support a CDN, so I may create static versions of its public assets; my installation is a manual upgrade anyway, so recreating the Brotli versions with each update would be trivial.
Final Thoughts
In addition to Scott Helme’s post, I found Sam Saffron’s review of Brotli to be very insightful: https://samsaffron.com/archive/2016/06/15/the-current-state-of-brotli-compression.
https://tools.keycdn.com/brotli-test is one way to confirm that Brotli is working. Responses can also be checked in the Network tab of Chrome and Firefox’s developer tools.