Dynamic Image Serving: imgproxy on AWS ECS

Loading https://wowa.ca on Fast 3G in Chrome Dev Tools before imgproxy
Loading https://wowa.ca on Fast 3G in Chrome Dev Tools after imgproxy
imgproxy vs. alternatives — https://github.com/imgproxy/imgproxy/blob/master/BENCHMARK.md
Basic Structure of AWS ECS

Utilizing Cloudfront CDN to address caching

Implementing dynamic image resizing can significantly increase latency, especially at a high number of concurrent requests, as resizing and converting images is a non-trivial task. If we processed images at every request, we would lose any advantages gained from a user experience perspective.

imgproxy on AWS

Securing Access to Our imgproxy Cluster

The low number of available concurrent requests means that our imgproxy is highly vulnerable to DDoS attacks. Anybody could use Postman and a link to an extra large image file to cripple the cluster. To secure access to our imgproxy cluster and ensure only authorized use, imgproxy implements and recommends for production signature-based hashing using a secret key and secret salt. The endpoint is hashed and the signature is added directly into the URL.

https://example.s3-website-us-east-1.amazonaws.com
https://example.com
https://other-example.com

WebP Automation

If you’ve used Google Lighthouse or the audit tool in Chrome Dev Tools, you’ll find that Google really really wants you to start using .webp formats for your images. Without legacy browser support for .webp, however, you’ll need to add a fallback. This is simple enough for a single image, but when you use responsive images you’ll end up with a huge chunk of code.

<picture>
<source type="image/webp"
srcset="images/example-300.webp 300w,
images/example-600.webp 600w,
images/example-800.webp 800w,
images/example.webp 1000w"
/>
<source srcset="images/example-300.jpg 300w,
images/example-600.jpg 600w,
images/example-800.jpg 800w,
images/example.jpg 1000w"
/>
<img src="images/example-300.jpg"
alt="Some Picture Description" />
</picture>

Simplifying Developer Coding

With imgproxy, it is now trivial for our developers to use responsive images. We created a function that accepts either a relative (e.g. /static/some-image.jpg) or absolute URL (https://example.com/some-image.jpg) and returns an imgproxy URL. This allows our developers to quickly code multiple responsive image formats without worrying about generating the image files and lets them quickly iterate through different resolutions. We were also able to remove legacy code from our backend that was used to pre-generate mobile images.

Further Optimizations

At Wowa, we’re always looking to improve. If you have any suggestions or alternative implementations, please let us know in the comments!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store