Web servers have been able to compress the content they serve for quite a while now. When they receive a request for an asset that lends itself to compression, usually a text file such as HTML or CSS it will compress it before sending it to the browser. The browser will then decompress the file and load it. This process cuts down on the amount of data that is served and also speeds up website loading.
The compression tool that has been used for this has been gzip. This is a solid compression algorithm but is getting quite old now. Google have developed a newer algorithm called Brotli that can be used in place of gzip.
Brotli has the advantage that for the same amount of CPU work a smaller compressed file is created. This magnifies the advantages of using compression to serve site content. In a dynamic configuration Apache will compress the website files every time they are served.
This can be avoided by pre-compressing the website files and getting Apache to serve the compressed files. This means that you only have to compress them once.
All the major browser - Chrome, Firefox, Safari, Edge - support brotli so lets configure Apache to use it.
Note, Apache is able to continue serving pages with gzip in addition to brotli and will only serve brotli compressed files to browsers that support it.
Install Brotli
This is usually a single package. On Debian, Ubuntu the following will work:
apt install brotli
And on CentOS and Fedora:
dnf install brotli
Compress some files
Not all browsers support brotli compression so you need to leave an uncompressed version next to the compressed file. This command will compress a file with brotli leaving the uncompressed original:
brotli -Z index.html
The -Z
option tells brotli to use the most aggressive compression level resulting in the smallest file.
Configure Apache
Apache ships with the brotli module and so it just needs enabling, along with mod_rewrite
on Ubuntu and Debian:
a2enmod brotli
a2enmod rewrite
Then restart Apache:
systemctl restart apache2
Now, open the VirtualHost entry for the site you want to serve the static files for. Add the following section:
<Files *.html.br>
AddType "text/html" .gz
AddEncoding br .br
</Files>
This tells Apache about .html.br
files. If you also want to compress .js
. .css
and .svg
(which you should) also add the following:
<Files *.js.br>
AddType "text/javascript" .br
AddEncoding br .br
</Files>
<Files *.css.br>
AddType "text/css" .br
AddEncoding br .br
</Files>
<Files *.svg.br>
AddType "image/svg+xml" .br
AddEncoding br .br
</Files>
Also, add the following rewrite rules that will send browsers that support brotli the compressed files:
RewriteEngine On
RewriteCond %{HTTP:Accept-Encoding} br
RewriteCond %{REQUEST_FILENAME}.br -f
RewriteRule ^(.*)$ $1.br [L]
Here is a complete, example VirtualHost file:
<VirtualHost 1.2.3.4:443>
DocumentRoot /var/www/
ServerName example.com
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
CustomLog /var/log/apache2/example.com.access.log common
ErrorLog /var/log/apache2/example.com.error.log
<Files *.html.br>
AddType "text/html" .br
AddEncoding br .br
</Files>
<Files *.js.br>
AddType "text/javascript" .br
AddEncoding br .br
</Files>
<Files *.css.br>
AddType "text/css" .br
AddEncoding br .br
</Files>
<Files *.svg.br>
AddType "image/svg+xml" .br
AddEncoding br .br
</Files>
RewriteEngine On
RewriteCond %{HTTP:Accept-Encoding} br
RewriteCond %{REQUEST_FILENAME}.br -f
RewriteRule ^(.*)$ $1.br [L]
</VirtualHost>
Finally, reload Apache:
systemctl restart apache2.service
Your webserver will now serve pre-compressed brotli content to browsers that support brotli.