Migrating assets to WebP and realizing these potential savings sounds great. So where do we start?
A better way to deliver images
In this blog, we will describe how to implement the conversion to WebP and how Amazon CloudFront and Amazon S3 can be configured to optimize and cache any website asset in order to gain web performance, improve image delivery, and give your users an accelerated experience.
Using a combination of Lambda@Edge and Amazon S3 Object Lambda we’ll show how an asset can be transformed according to the requirements of the browser, stored in S3 for future reuse, cached within Amazon CloudFront and finally cached in the browser.
What would the solution look like?
For this blog post, we’ll use the following reference implementation to explore each step of the process in detail. When you’re ready to implement this on your site see the repo here.
Let’s walk through the chain of events triggered when a user clicks a link on your site.
Initial Request
First, the browser is checked for WebP support. After that support is confirmed, it appends the query string transform=ABC to the HTTP request when fetching the asset cat.jpg.
Then Amazon CloudFront executes an origin request (a Lambda@Edge function) to determine if a transformation was requested. If a transformation is needed it will mutate the S3 key to fetch the correct object from Amazon S3.
The Lambda@Edge function tells Amazon CloudFront to use transform=ABC/cat.jpg rather than cat.jpg as a S3 key as indicated in the code snippet #1
Failed Request and Image Conversion
The original request through Amazon CloudFront tries to fetch the S3 key transform=ABC/cat.jpg from the S3 bucket, but does not find it because it hasn’t been produced yet. Based on this failed response Amazon CloudFront executes an origin response Lambda@Edge function to try to convert the failed response from S3 into a resized image. The origin response Lambda@Edge function directs the requested transformation ABC to a specific Amazon S3 Object Lambda access point and fetches the cat.jpg S3 key through it as indicated in the code snippet #2.
Amazon S3 Object Lambda executes an AWS Lambda function to transform the image cat.jpg using the reference transformation ABC.
Storing in S3 for Future Reuse and Delivering the Image
The AWS Lambda function will keep a copy of the transformed image in the S3 bucket for the next time that Amazon CloudFront needs it. But to help the origin response Lambda@Edge function finish its execution, it saves it after delivering the optimized asset to Amazon S3 Object Lambda.
The origin response Lambda@Edge function embeds the optimized image bytes into the response object that it will return to Amazon CloudFront as indicated in the code snippet #3.
Amazon CloudFront returns the resized image to the browser with a Cache-Control HTTP header that will instruct it to cache the asset for a long time while Amazon CloudFront will also cache it for as long as its cache policy allows it.
An Example
Given this original image in its current form as a non-optimized JPG:
If it is fetched from this updated URL which uses the query string transformation-template = webp-20230802-460 to optimize the delivery of a transformed image, a significant reduction in size can be seen.
The original image weighs 727,763 bytes versus the transformed image weighing only 16,730 bytes. This significant reduction means that the 700,000+ bytes that weren’t delivered to your user will speed up the user experience every single time that asset is requested.
If you haven’t already, click the links for the original, non-optimized image and the transformed, optimized image and compare the speed of the request and optimization of the delivered image. The results are striking.
Conclusion
With today’s modern technology that includes screaming fast WiFi and gobs of RAM in every device it may feel like the need for image optimization has become less important. However, as the example above shows, you can measurably and significantly speed up image delivery on your site and have a direct impact on the browsing experience for your users.