Faster Paint Metrics with Responsive Image Optimization CDNs
When you are interested in web performance, image compression and optimization are key aspects to consider that will impact many user-centric metrics, such as First Meaningful Paint and Speed Index. I’ve researched the image optimization solutions offered by the main CDN providers in order to identify the most relevant techniques in use today to map the differences among providers and help you pick one in case you need them. I also looked at what opportunities for improvement are still there.
Pictures are worth a thousand words… if they load
On average 51% transferred bytes on a page load are images, and more than half of those bytes are used above the fold, so they impact performance metrics. With thousands of different devices browsing the web today, offering the best image for each context is challenging.
Today, the context to decide the right image includes layout dimensions, pixel density (dpr), the best format supported (such as WebP, APNG, JPEG2000, or just classic web formats), user’s data-saving preferences and connection speeds.
A default website without a truly responsive images solution typically involves the creation of 1 to 5 different versions of one image, but to provide the best possible experience and best performance results we need to create n different variants of the same image. That’s were image optimization CDN providers come in handy in addition to their traditional function of caching content at the edge, they take care of image compression, reformat, resize and other techniques in the cloud, as a service, with a Content Delivery Network in place that will serve that file closer to the user.
Why image optimization CDNs help in Web Performance?
When you run a lighthouse test, typically you see a list of opportunities to help the user-centric metrics. Many of those opportunities are around image manipulation and image optimization CDNs can help you with those without too much work on your side.
Providers in this research
The research includes well-known names in the web industry, such as Akamai’s Image Manager, Cloudflare’s Polish & Mirage, and ScientiaMobile’s Image Engine. In addition to those, I’ve added some new names in the field, such as ImgIX, Fastly’s ImageOptimizer and CloudImage. Some providers not offering CDN services (such as ImageKit, Cloudinary) were worth mentioning as they are addressing the same use-case, albeit with a different approach.
I identified three kinds of providers:
- General Purpose CDNs, such as Akamai, Fastly or Cloudflare. They offer image compression services as an add-on or a product on top of their main solutions. Typically these solutions involve changing your main DNS entry or directly the DNS server in your domain registrar. Usually, we don’t need to change our HTML image references to deploy these solutions. These cases involve a bigger deal, as they affect more than just image loading.
- Image Optimization CDNs such as ImgIX, CloudImage or ImageEngine that are mainly focused on images and can be used with any architecture. These solutions typically involve referencing to a different domain (such as images.mydomain.com) which may require changing all the image references in the HTML either manually or through an SDK.
- Image Optimization Services with external CDNs: Some providers in the research are not offering CDN services, only mage optimization services, but they might use an external basic CDN service in their solutions, such as Amazon CloudFront. In those cases, you can also integrate other general-purpose CDN on top to have a full or better CDN coverage.
Here you can see a comparison of the main features available from each CDN providers, before seeing results from testing.
Web Performance Summary
If you are out of time, let’s see a summary of the impact that each provider might have on your web performance by optimizing responsive images.
There are generally two ways to obtain images in optimized format or dimensions with these providers:
- Explicit directives: where we specify width, height, format, etc. of the image that we would like to obtain back from the CDN or service. This is typically paired with certain automatism, so requesting a page with a given width will cause the height to be automatically calculated to maintain the aspect ratio for example.
- Automatic transformations: relying on the CDN to understand the context of the request and apply the most suitable parameters for the transformation.
When doing responsive images, we’d like to let the CDN pick the best format and dimensions based on the context and the placeholder for the image to keep our HTML semantic and without the need of client-side code, so I will focus more on automatic transformations in my testing. When doing native apps and you have full control of image loading, you might want to see more on the explicit directives side of CDNs.
For making the selection, every provider relies on the Accept header -for example, by checking for WebP support-. Some providers also rely on Client Hints when available.
Device Library Support
ImageEngine seems to be the only provider publicly known to employ a device detection library within its decision algorithm. ImageEngine uses the well-known WURFL library to detect the device from the User-Agent string and other HTTP headers, to then make a decision regarding screen width, screen density and best-supported format for a given image for a given device, even if no Accept header is explicitly supporting that selection.
That’s why ImageEngine appears to be the only CDN capable of rendering an image as a percentage of the available device width. For example, you can request an image of 100% or 60% of the screen from the URL without specifying the actual layout or physical pixels. All the other CDNs need a pixel definition which makes things more manual with so many breakpoints to define for some responsive layouts.
Client Hints is one of the current useful (but less well-known by the web community) features offered by browsers. In fact, finding accurate information about current compatibility and support was hard. There is a good update article explaining Client Hints in developers.google, but it doesn’t provide info about compatibility.
Things get even more complicated in the case of image CDN solutions as we are loading images from cross-origin servers (i.e. images.mydomain.com) instead of from first-origin (i.e. mydomain.com). Because of some privacy concerns, Chromium has decided to limit Client Hints to cross origins, and I couldn’t find updated information on the matter. Therefore, it was time fa little research.
Client Hints are sometimes even better than using a server-side library as they can, for example, take current zoom level on a desktop or a user’s preference in scale on mobile devices into consideration. For example, a Retina MacBook with a DPR of 2 will send a DPR or 2.50 to the server if you zoom in your browser by 125%. On Android, a Pixel 3A with a DPR of 2.5 will expose a DPR of 3.375 if Display Size is set to “larger” in Settings, or will expose 2.3375 when it is set to “small”.
Akamai has offered image optimization based on the real RTT without Client-Hints for a while in a separate product called Adaptive Image Compression but I couldn’t test anything from Akamai.
Current available Client Hints are: viewport-width, dpr (device pixel ratio or pixel density), width (when the browser knows the exact width needed for an image), ECT (effective connection type, such as 2g, 3g or 4g), RTT (round trip time, related to the network latency), downlink (estimated download bandwidth), device-memory (expressed in GiB rounded to a limited set such as 0.5, 1, 2, 4 or 8) and save-data that will expose user’s intent to reduce bandwidth usage. With this information, the server can make smarter decisions regarding image transformation and send the best image to the client.
As of September, 2019 this is the compatibility of Client Hints support for first-origin images (such as when you use Cloudflare or Akamai) and cross-origin images (such as when you use ImageEngine or CloudImage).
Based on that compatibility, today if an Image CDN supports Client Hints, these are the percentage of visitors that can receive more accurate images to their situation:
- First-origin CDNs —73% of desktop users and 67% of mobile users
- Cross-origin CDNs — No desktop users and 61% of mobile users
In general, this means that if you select a first-origin CDN provider, 70% of your visitors can take advantage of using Client Hints. For a cross-origin CDN, 34% of your visitors can take advantage of them.
With a Service Worker proxy, you can add Client Hints to more than 90% of your visitors, so in that case, the possible advantages are higher, but I haven’t seen this technique in usage too much yet.
The Save-Data Client Hint
The Save-Data is the only hint that doesn’t need being opted-in by the developer. If the user enables Save Data in settings, a compatible browser will send that HTTP header automatically. For example, iOS 13 adds a “Low Data Mode” on cellular networks, so Safari can add the Save-Data header, even if they are not supporting Client Hints yet. Unfortunately, Safari is not honoring that setting yet.
According to the recent article from Tim Kadlec on Save-Data Usage, between 4% and 20% of your users might have the data saver settings enabled, based on your audience geography and type. When we blend those stats with current compatibility of the feature, we can conclude that supporting Save Data to compress our images even further, will increase performance and honor user’s choice for 1% to 6% of your total visits. The impact of these numbers is even bigger when you realize that typically those users are browsing the web under poor network conditions.
Now it’s time to look at Client-Hints support by Image Compression CDNs based on my testing.
We can see that no CDN takes advantage of the network-related client-hint. In this case, only first-origin CDNs could take advantage of it, but none is actually doing it. The idea is that if the RTT is too high, or if the ECT is actually 2g or slow-2g we know for sure we must send a high-compressed version of the image.
Also, no image CDN is taking advantage of the device memory client hint, even if all of them are able to access that data as long as the developer opts-in into it. In cases like this, we could make a difference between a high-end Android and a low-end Android, or between an old desktop with 1GiB of RAM vs a high-end laptop with +8GiB of RAM, even if both are using the same desktop OS and browser.
Supported File Formats
Input Formats diversity
Every provider accepts the well-known PNG and JPEG files for optimizing, but not all of them accept SVG files or animations as input. CDNs that do not support a given file format will simply ignore the file and just bypass it through the CDN without any compression or transformation.
Output Formats diversity
Every provider supports converting images into WebP format if the Accept header is present. That’s basic for all CDNs; however, only ImageEngine goes beyond PNG, JPEG, and WebP.
Sometimes picking the format only based on the browser might lead to a bigger file; for example, ImageKit delivers WebP files to compatible browsers only if the WebP file is smaller than the same image in PNG or JPEG. So the same image to the same browser might be delivered in WebP or PNG for example based on the screen size to maximize data transfer opportunities.
ImageEngine is the only provider in the test offering JPEG-2000 format (JP2 files); Akamai says the format is available based on the documentation, but I couldn’t test it. This format is useful for Safari on macOS, and for all iOS and iPadOS browsers. That is a great advantage over the other CDNs, as WebP is not available on these browsers yet, and JPEG-2000 files will typically be smaller than a normal JPEG with the same visual quality. This is done thanks to the usage of a device detection library because, for some reason, WebKit does not expose image/jp2 support on the Accept header; CDNs that rely exclusively on HTTP headers, won’t know that JPEG-2000 is available and will rely on classic compressed PNGs or JPEGs.
JPEG-XR was important for a while to support IE and Edge, but I didn’t test this as I think in terms of market share it’s not important and it will be less important in the future with Edge moving to Chromium and WebP support.
Similarly, ImageEngine is the only CDN being able to convert animated GIFs into Animated WebP for Android and Chrome mainly, and into MPEG-4 videos, supported now on <img> elements on Safari for macOS, iOS and iPadOS.
Cloudinary knows about JPEG-2000, but what they said is: “JPEG 2000 is better only if you need transparency or for huge images. Encoding JPEG 2000 is slower and CPU intensive and also with f_auto it will add another transformation. So we do not support automatic delivery of JPEG 2000”
Optimizing Images without any manual sizing
Every provider let you provide arguments to define the exact width and height that you prefer for the image, and also the resulting format (JPEG, PNG, WebP, etc.). While that ability might be good for image management in general and for native apps, it’s not something interesting for web design as we just want to load the best possible image for the current context, without the need to define every argument explicitly.
In this case, I analyze what happens in each CDN provider with bitmaps when we have an img element without any manual size declaration with something like:
<img src=”https://cloud-url/image” sizes=”100vw” alt=”no size declaration in URL”>
As you can see ImageEngine beats all the other providers in this category by far. The main reason is the usage of a device detection library that let it resize the image to the maximum available width for each device. That’s also something you might not want, so use with care. Finally, iPhones won’t get the right size or resolution because Apple decided to mask the iPhone model from the user agent, so a generic iPhone (the least powerful hardware supporting that iOS version) is always assumed by ImageEngine.
Optimizing Images with Explicit Size Declaration
In this case, I analyze what happens in each CDN provider when we have an img element declaring sizes explicitly in the URL to inform the CDN about the image that we are expecting. We can use this technique to specify different sizes with srcset and <picture>. I didn’t set different versions per dpr class (i.e. 2x, 3x) in order to observe how different CDNs react to the requests. However, Client Hints were on for compatible CDNs and browsers.
In this case, there is more balance between providers, and it seems the best way today to use most image CDNs which makes things more complicated when you want to define sizes in CSS. ImageEngine doesn’t take DPR into consideration, so, for example, a 100px image for a Galaxy 10 phone returns a 100 physical pixels image instead of a 400px image as other CDN providers. That’s not the case when you use ImageEngine automatically without explicit sizing, so sometimes it gets difficult to find the balance to fairly compare providers in this field
Compression Ratio on the exact same size
In this test, I checked every provider asking for one specific width and height, without Client Hints, just to see how many bytes are returned in the same file with the same exact physical dimensions. The test was done using a WebP-compatible browser, Safari (that might include JPEG-2000 support), and other browsers.
Optimizing Vector Graphics
SVG files are often ignored by Image Compression CDNs, but here Cloudinary and CloudImage exhibit a difference: they convert the SVG into a bitmap. The final bitmap image has different sizes for different devices, but I couldn’t find a consistent answer to how they calculate those sizes. Cloudinary seems to define the final size based on a device library, and CloudImage just picked a 1800px width for the bitmap version for all devices. To be honest, I’m not sure this is something web designers will want for SVG-compatible browsers; in fact, for some devices, the WebP result from the CDN is bigger in size than the original SVG served with GZIP or Brotli.
Most CDNs, such as ImageEngine or Cloudflare, are serving the file compressed with either GZIP or Brotli based on browser compatibility as SVG is the only image format that is text-based.
Animated GIFs can be really painful for web performance because it’s a very old and unoptimized format. In these tests, I analyzed each CDN and what they do with these files, including format conversion (APNG, AWebP or MP4) and resizing.
ImageEngine is the only provider resizing and converting animations into other formats (Animated WebP or MP4 videos), other CDNs such as ImageKit and Cloudflare don’t convert the file but they compress the GIF if possible.
Impact on User-Centric metrics
I used WebPageTest to run Lighthouse on a fast 3G mobile phone, and on a desktop with a cable connection to see the impact on user-centric metrics and data file transfer (images only) compared with the original website with no optimization image CDN usage.
Final results vary by site by site and for some CDNs such as Fastly or Cloudflare, we need to understand user-centric metrics are also enhanced by web performance optimization techniques that are besides image manipulation, so it’s difficult to find the balance in the comparison. For this reason, I applied a different score for those providers.
If you have a website with an average or high amount of images, using a responsive image CDN solution might get mandatory if you want to increase your user-centric paint metrics. Testing the CDNs wasn’t easy; there are many challenges and differences in adopted practices but I hope you can now have a better idea of the different solutions in the market, their differences and their technical advantages.
Device-detection is definitely something nice to see in an image compression CDN because Client-Hints are not available today on all browsers, not everything can be detected with Accept headers and web designers want to define responsive images in the simplest way possible. Most of the CDNs lack support for this. ImageEngine is the only one that I could confirm use a device library to make decisions server-side.
But there are also some other features not seen on any CDNs that might impact web performance so there is still room for improvement in the future. The list includes usage of the Device-Memory hint, the network client hints (useful today only for first-party domain CDNs), a service worker library support to increase the ability to help the server or the usage today of QUIC over HTTP (the future HTTP/3).
Disclaimer about the tests
For most providers, testing the service was simple: registering for a trial account, checking documentation and testing in a couple of minutes. General Purpose CDNs such as Cloudflare took a bit more time, including changing the DNS server in the registrar (and even paying the Pro account — no image compression service on a free tier).
For testing I’ve used one of the most downloaded free creative commons HTML templates including their included images and some other images of my own, trying to be as diverse as possible: backgrounds, logos, icons, images with people, animations and an SVG file. Tests were made in September 2019, so if you are reading this in the future, the CDNs might have changed what they offer.
I’ve tested with desktop browsers and a diverse set of mobile devices: including an iPhone, a high-end Android, a low-end Android, a kaiOS feature phone, an iPad, and an Android tablet. On compatible browsers, I enabled Client Hints to see if there was any reaction, and I also tested the Save-Data flag.
On every provider, I tried to set up the CDN to work as automatically as possible in terms of format and quality selection, including setting WebP automatic selection if available.
There was one CDN that was not available for testing, so the information will be based only on published documentation: Akamai. As far as I can tell, image compression is not something they are so interested in selling, so I couldn’t test their solutions, even if I was willing to pay a basic tier if needed. Getting a trial (or paid) account set up for image compression took too much time, including emails back and forth with at least 5 people copied on the exchanges on how and why. In the end, after three weeks of trying, I gave up. As of today, I still don’t have access to an Akamai account to test image optimization.
Disclaimer: after publishing the first version of the article, Akamai contacted me with some information about their service -still no access to test it- and many features that will come in the near future.
Fastly, on the other hand, claim on their website that you can test their Image Optimization solution with the Trial account, but this turned up to not be the case when I signed up. I contacted their support and after two weeks, and as an exception for this article, I was finally able to get my developer account set up and I could start testing their image optimization service.
Maximiliano Firtman is a mobile + web developer, trainer, speaker, and writer. He has authored many books, including High Performance Mobile Web published by O’Reilly Media. He is a frequent speaker at conferences worldwide and he has been widely recognized for his work in the mobile-web community. He teaches mobile, HTML5, PWA and web performance trainings for top companies around the world. He has delivered several Progressive Web Apps workshops and trainings at many companies and at online publishers, such as Linked Learning, Pluralsight, and O’Reilly Learning. Twitter: @firt