Brotli compression delivered from AWS
Edit: On July 11th, 2018 Amazon added support for whitelisting the Accept-Encoding HTTP header 🎉 ! You can now use brotli without using the viewer request.
https://forums.aws.amazon.com/message.jspa?messageID=850934#850934
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html
What is Brotli?
Brotli is a generic-purpose lossless compression algorithm released by Google in 2015, similar to the common gzip it can be used to compress data and send it over the network.
Why?
It provides better compression than gzip, in particular:
- 14% smaller than gzip for JavaScript
- 21% smaller than gzip for HTML
- 17% smaller than gzip for CSS
You can read more details in the Akamai blog post here: https://blogs.akamai.com/2016/02/understanding-brotlis-potential.html.
Which Browsers support it?
Pretty much all the modern browsers, caniuse.com has a nice visualisation of the coverage support here.
Setup for AWS (CloudFront + S3 + Lambda = ⚡️)
In this article we will explore the setup of Brotli compressed content on AWS infrastructure. We will use CloudFront, S3 Bucket and Lambda functions.
CloudFront is a web service that speeds up distribution of your static and dynamic web content, a.k.a. Content Delivery Network (CDN). This is basic service for running scalable applications with minimum latency across the globe. It gives you the ability to compress and deliver in gzip but unfortunately not in Brotli at the moment. AWS documentation in here.
Amazon S3 is cloud storage for the Internet and this example will be our origin server.
Lambda is an event-driven and serverless computing platform. A great feature has been recently announced and will allow to run code at CloudFront events: Lamda@Edge. These are the events that can trigger Lambda functions and manipulate requests and responses.
This approach is very simple and allows CloudFront Cache to deliver the right content based on the Client request:
- Compress files at build time and provide Gzip and Brotli version.
- Upload your build files in 2 separate paths of the S3 Bucket.
3. Update files metadata and add content-encoding
with gzip
or br
in every file based on the folder.
4. Now that S3 Bucket is set, let’s create the Lambda functions.
- Go to AWS Lambda in AWS console
- Create a function with new name viewer-request-handler
- Paste the following NodeJs code.
This step is required because if the
Accept-Encoding
header includes additional values such asbr
, CloudFront removes them before forwarding the request to the origin server. (As documentation say here)
5. Let’s create the last handler: lambda-edge-origin-request-handler
6. Now everything is ready to be connected. We need to attach the handler to the right events. Go to the AWS console and config the CloudFront distribution and it’s handlers:
Conclusion
Some further investigation would be needed to estimate the cost of this process, especially since these functions will be triggered for every user request.
Brotli will be largely used soon as it provides more compression than gzip, I do believe that AWS CloudFront will include this compression type in his infrastructure saving configuration costs.