Use Brotli Compression

Reliably serve brotli compressed files with gzip fallback while ensuring no compression overhead when serving brotli files.

Last Updated : April 16, 2019


How much will it benefit your website performance?

Serving brotli compressed files helps reduce transfer size for HTML, CSS, JS and SVG files, but not JPG, PNG, WebP, GIFs. So, the over-all speed benefit will be reduction in download time for files of above mentioned types. The speed benefit depends on how much compression you achieve for your files. For top five pages on our website, www.tezify.com, we observed a 20-43% reduction in page's total transfer size (total data downloaded for a page to display).

For top five pages on our website (www.tezify.com), brotli compression reduced the page's total transfer size (total data downloaded to display a page) by 20% to 43%.

Generating brotli compressed files

Brotli compression can be CPU intensive. This means, compressing your files into brotli format through web server while serving a request is a bad idea. Instead, you should pre-compress and store brotli compressed files for your HTML, CSS, JS and SVG files. This should be done during build & deploy. You can use one of the following to brotli compress your files:

With any of the above, your goal should be to have brotli compressed files next to your regular files (style.css should have a corresponding style.css.br)

Serving brotli compressed files via Nginx

You can use Google's Nginx module for Brotli to serve generated brotli files. Once installed, below is the recommended Nginx configuration (generally goes into /etc/nginx/nginx.conf):

http{
	...
	...
	brotli_static on;
	brotli_types text/plain text/css application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/x-icon image/vnd.microsoft.icon image/bmp image/svg+xml;
}

If installing / adding ngx_brotli is problematic, you can add the following configuration within your server block to serve pre-compressed brotli files:

server{
  ...
  ...
  location ~ (.+)\.(css|js|svg)$ {
    set $brotlify "";
    if ($http_accept_encoding ~ br) {
      set $brotlify "Y";
    }
    if (-f $request_filename.br) {
      set $brotlify "${brotlify}ES";
    }
    if ( $request_filename ~ (.+)\.css$ ){
      set $cType  "text/css";
    }
    if ( $request_filename ~ (.+)\.js$ ){
      set $cType "application/javascript";
    }
    if ( $request_filename ~ (.+)\.svg$ ){
      set $cType "image/svg+xml";
    }
    if ( $brotlify = "YES" ) {
      gzip off;
      add_header Content-Type $cType;
      add_header Content-Encoding br;
      add_header Vary Accept-Encoding;
      rewrite (.*) $1.br break;
    }
  }
  ...
  ...
}

Serving brotli compressed files via Apache

Add the following within your <VirtualHost> within your apache configuration file (typically within /etc/apache2/sites-enabled/):

<VirtualHost \*:443>
...
...
RewriteEngine On
RewriteCond %{HTTP:Accept-Encoding} br
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME}.br -f
RewriteRule ^(.*)$ $1.br [L]
RewriteRule "\.br$" "-" [NS,E=no-gzip:1,E=dont-vary:1]
<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>
<Files *.html.br>
    AddType "text/html" .br
    AddEncoding br .br
</Files>
</VirtualHost>

CDN specific changes to serve brotli files

If you are leveraging a CDN, chances are that despite the above configuration, brotli compressed files may not be served to your visitors. You may have to make additional changes depending on your CDN provider:

  • With Cloudflare, you can serve Brotli compressed files by just enabling it via UI (no web server side configuration required): Enabling Cloudflare Brotli compression
  • With AWS Cloudfront, you can enable Brotli compression by Whitelisting 'Accept-Encoding' header: Enabling AWS Cloudfront Brotli compression
    To set this up from your AWS web console, edit the Behavior settings of the Cloudfront distribution. Here, select 'Whitelist' for 'Cache Based on Selected Request Headers'. Once selected, the UI allows you to select the request header you want ot use for whitelisting. Select 'Accept-Encoding'.

    You also need to disable Cloudfront from compressing objects automatically: Disabling automatic compression from AWS Cloudfront

Note : In case if IIS is your origin server, you will have to set noCompressionForProxies to false within your application and web config. Refer here for more details.

Verifying if your site is serving brotli files

To verify if your pages are served brotli compressed or no, run the following command for your website's URL and look for the value within 'Content-Encoding' in the response header. If it is 'br' like in the screenshot below, your brotli compression setup is working as expected.

curl -H "Accept-Encoding: br" -I <Enter Your URL Here>
Verifying Brotli configuration


Punit Sethi

About the Author

Punit Sethi has been working with large e-Commerce & B2C websites on improving their site speed, scalability and frontend architecture. He tweets on these topics here.

Also Read