Efficient Image Tags
Some time ago, I wrote x-image
, a custom HTML Web Component for including images that, given a list of candidate images, will automatically select the smallest image required to for the available space and resolution. The goal is to reduce page sizes while ensuring high quailty images, and without adding an unnecessary burden on site authors. Having recently taken some time to page it back in and some reliability issues with the approach as part of my December Adventure, I thought it might finally be time to write it up.
x-image
looks like this:
<x-image width="640" height="480">
<x-source width="320" height="240" src="small.jpg"></x-source>
<x-source width="640" height="480" src="medium.jpg"></x-source>
<x-source width="1280" height="960" src="large.jpg"></x-source>
<img width="320" height="240" src="small.png" />
</x-image>
The top-level width
and height
attributes specify the ‘natural’ size of the image at 1x scale and the nested x-source
tags provide different candidate images alongside their natural sizes. This is sufficient information for the web component to select the smallest image source large enough to display at native resolution and fill the space available to the x-image
tag. For example, if the above HTML is rendered in a page or component with a maximum width of 320, at a scale of 1x, small.jpg
will always be used; if it’s displayed without any external size constraints, at a scale of 2x, large.jpg
will be displayed at a size of 640x480 dips.
x
Funamentally, x-image
shouldn’t need to exist—the functionality it offers almost exactly matches the documented behavior of the img
srcset
attribute. Unfortunately, experiments and observations have convinced me, while most browsers honor the scale of image sources, they disregard the size at which an img
tag is being displayed, always selecting the largest image available for a given scale.
x-image
As I mentioned above, x-image
is a JavaScript extension that’s intended to run client-side to automatically select appropriate size and resolution assets to fill resizable images, without needing complex hand-crafted HTML, JavaScript, or CSS media queries. It exists because, try as I might, I’ve never been able to convince myself that the img
srcset
attribute works in any helpful way—browsers will select an image matching the native scale (2x, 3x, etc), but never select an image that matches the render size, meaning that they will consistently select they largest image you offer up in the srcset
, bandwidth be damned. (I really wish I x-image
didn’t need to exist so, if I’m missing something, please reach out and let me know!)
In a lttle more detail, taking Jon’s example:
The JavaScript DOM element
If you’d like me to write more about either InContext or x-image
, please get in touch. I wrote both for my own use first and foremost, but they’re both open source and I love it when the things I crate help others.