This guide dives into image optimization, but all recommendations and APIs are also compatible with videos (currently in beta.)
Responsive development empowers developers to tailor websites to each user’s device. It brings the challenge of optimizing bandwidth usage to load only what is needed. Creating responsive image variants is key to creating engaging experiences on the web. But it comes at a price: the more variants you have, the less you can benefit from caching, a strong performance enabler.
A Song of Variants and Cache
Accommodating to any device widths is now foundational to web experiences. For images, responsiveness is only the first step; media optimization is the second. You don’t need a 1000px wide image for that profile picture displayed as a 64px circle. But the keystone of responsive images is art direction: an image that looks good in full width on desktop might need a zoom effect when displayed as a square on mobile. TwicPics transformations API include smart-cropping that makes responsive art direction a breeze.
Still, the Web Almanac of 2021 reported that only 2% of websites listed more than 10 candidates in the images
srcset; more than 80% listed 5 or less. Best practices are largely not implemented in this regard. Given screen widths ranging from 320px to 4K and varying device-pixel ratios, we approximate a good number of variants to be between 10 and 20 depending on the image ratio to the viewport. Handling that many variants can be cumbersome for designers and developers alike as creation (or generation), storage, caching, and integration become more complex as the number of variants increase.
Fortunately, context-aware optimization solutions like TwicPics remove all the extra work, as the on-demand API enables generation of an infinite number of pixel-perfect variants. But the actual number of variants is strongly related to the caching performance. In some scenarios, it is more optimal to reuse a variant that is close enough to the desired dimensions. This allows benefiting from CDN caching without noticeable quality difference. Pushing the number of variants ever higher effectively means decreasing the effectiveness of caching as more media requests would result in a cache miss.
Limiting the number of variants with step
With an on-demand optimization solution, the challenge eventually becomes to settle on the number of variants to generate. It needs to be high enough to optimize the bandwidth usage, but it should remain low enough to maximize the effectiveness of caching. TwicPics implements a step API that gives developers the ability to limit the number of variants to multiple. A 50-pixel step would only generate variants for a minimum of 50 pixels difference. In practice, it means two images with respective displayed sizes of 310px and 320px would both use the same 300px variant.
With Twicpics, we recommend setting a default step of 50 using the global configuration:
<script async defer src="https://sub.twic.pics/?v1&step=50"></script> <!-- For components, step can be configured at the module initialization -->
Media variants also aim at addressing screens with different pixel density. For pixel densities above 2, bandwidth costs grow exponentially, while the perceived quality improvement becomes smaller. As such, it is recommended to limit variant generation to device-pixel ratio of 2. To encourage these best practices, TwicPics sets a default value of 2 for the maximum DPR.
A note on the number of
srcset candidates—it’s important to keep the HTML parsing time in mind. Although somewhat of an edge case, adding very long lists of variants in the
srcset attribute might bloat the HTML, which in some cases result in noticeable delay for the first render (which is counter-productive from a performance standpoint.) This issue does not exist with context-aware solutions that only request the needed media. But context-aware optimization notably fall short for images that cannot be lazy loaded (hello LCP), so we wrote an in-depth guide on how to optimize the Largest Contentful Paint image.
A step of 50px is a good default for most images, but media displayed at the full device width—like hero images—should have a higher step so as to further limit the number of variants. For such images, we recommend setting a step of 200 pixels. You can do so at the image level with the following image syntax.
<!-- Using vanilla JS --> <img data-twic-src="image.png" data-twic-step="200" /> <!-- Using TwicPics components --> <TwicImg src="image.png" step="200" />
To find the optimal balance between the number of variants and performance, you need to account for the following:
- Limit variants to a maximum of 20 to optimize CDN cache hits — use a step of 50 on average, 200 for hero images
- Do not generate variants for pixel density higher than 2
- Keep the HTML parse time reasonable