
Application Performance - Image optimization
Images are commonly the heaviest components of a web page. Optimize images to improve user experience, reduce content delivery costs, and enhance SEO.
- What image transformations are needed? Is it formatting, resizing, cropping, etc.
- Where do we decide which transformation to be applied for a specific image request? In the front-end on the client-side (static, responsive design, etc.), on the server side (based on request content such as device) or combination of both?
- Where do we execute the transformation? In a central location or in a distributed way?
- When do we execute the transformation? Every time or do we store transformed images for a short duration? Is it synchronously or asynchronously executed?
- The user sends an HTTP request for an image with specific transformations, such as encoding and size. The transformations are encoded in the URL, more precisely as query parameters. An example URL would look like this: https://exmaples.com/images/cats/mycat.jpg?format=webp&width=200.
- The request is processed by a nearby CloudFront edge location providing the best performance. Before passing the request upstream, a CloudFront Function is executed on viewer request event to rewrite the request URL. CloudFront Functions is a feature of CloudFront that allows you to write lightweight functions in JavaScript for high-scale, latency-sensitive CDN customizations. In our architecture, we rewrite the URL to validate the requested transformations and normalize the URL by ordering transformations and convert them to lower case to increase the cache hit ratio. When an automatic transformation is requested, the function also decides about the best one to apply. For example, if the user asks for the most optimized image format (JPEG,WebP, or AVIF) using the directive format=auto, CloudFront Function will select the best format based on the Accept header present in the request.
- If the requested image is already cached in CloudFront then there will be a cache hit and the image is returned from CloudFront cache. To increase the cache hit ratio, we enable Origin Shield, a feature of CloudFront that acts as an additional layer of caching before the origin, to further offload it from requests. If the Image is not in CloudFront cache, then the request will be forwarded to an S3 bucket, which is created to store the transformed images. If the requested image is already transformed and stored in S3, then it is simply served and cached in CloudFront.
- Otherwise, S3 will respond with a 403 error code, which is detected by CloudFront’s Origin Failover. Thanks to this native feature, CloudFront retries the same URL but this time using the secondary origin based on Lambda function URL. When invoked, the Lambda function downloads the original image from another S3 bucket, where original images are stored, transforms it using Sharp library, stores the transformed image in S3, then serve it through CloudFront where it will be cached for future requests.
Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.