Edit: October 2022 – I’ve also added tutorial for configuring nginx with brotli compression with gzip fallback (handling both statically compressed files and dynamic content):
Brotli is a relatively new generic-purpose lossless compression algorithm that compresses data using a combination of a modern variant of the LZ77 algorithm, Huffman coding, and 2nd order context modeling.
For our purposes, we just should know that it offers significantly better compression ratios and thus smaller file sizes. Smaller file sizes then mean faster site loads.
According to caniuse, most modern browsers do support brotli natively these days:
It is however still recommended to support both brotli and gzip if possible, hence this article.
What assets should I cache?
Typically it is recommended to only compress text-based formats, such as html, css, js and similar.
You are very unlikely to benefit from compressing already compressed formats such as png, jpeg, gif etc.
As a point of comparison – I like to refer people to aws cloudfront compression list that offers some insights into what formats AWS considers well-compressible (hint: binary formats are not on it).
Install brotli and deflate
I’m using ubuntu 20.04 (with Apache/2.4.41) in my case, your syntax will of course be a little different in alpine/rpm or other distros.
sudo apt-get install brotli sudo a2enmod brotli sudo a2enmod deflate #deflate module automatically enables gzip compression or certain types, however this is best configured by us, as we need brotli as well. rm -f /etc/apache2/mods-enabled/deflate.conf
Note that at least in ubuntu 20.04 – mod_deflate automatically enables gzip’ping of certain content by default once installed and enabled.
This turned out to be a problem for me as we would want brotli to be used by default with gzip only being a fallback.
Thus in the example above I’ve removed /etc/apache2/mods-enabled/deflate.conf file.
Do not re-compress already compressed brotli and gzip files
It s possible that we pre-compress some assets as .gzip or .br files so apache wouldn’t have to re-compress assets every time.
This is just sensible thing to do and should lead to shorter response times in theory. We can easily add brotli compression into our gulp/webpack pipeline (I’ll make a post on this at a later time.)
Without a further adue:
Now – the above snippet will check if there is a file on the server with exactly the same filename, but with .br extension (or .gzip extension) and redirect the request to that file.
Apache – compress dynamic content as brotli (with gzip fallback)
After static pre-compressed content is dealt with, we should address dynamic content and anything else that is not pre-compressed but can be compressed effectively.
This snippet should be added below snippet dealing with static content.
Here – I’m only compressing on the fly the most typical content types: css, js, html, svg (svg is text/xml based format so is compressible) -> many applications might have different requirements so ymmv (adjust as needed).
Note – you need to add brotli before gzip in order for it to be a preferred compression mechanism: