Automatic integration of srcset on images

Hello,

Following Load images lazily by default, see below a proposal for the use of the srcset attribute for images, allowing to minimize the bandwidth usage of images.

Currently, when an image is inserted a page content its width is based on the following constraints:

  1. not larger than 100% of the viewport
  2. not larger than the optionally defined width

If no width is defined, the system loads the image at its full size. If a width is defined, the system scales the image to that width, loading a smaller version of the original.
Defining a width is already a gain in terms of bandwidth but:

  1. requires to manually input a size
  2. if the size is set to 800px, but the user’s viewport is 400px (e.g., on a smartphone), the 800px image is loaded nonetheless.

Luckily, srcset had been introduced and is supported by all the major browsers (see | Can I use... Support tables for HTML5, CSS3, etc). And, when not supported, the browser just ignores the attribute and uses the src attribute.

I won’t go into the detail as articles such as Load images lazily by default - #6 by mleduc are explaining it better than I could.
But, to explain it quickly, srcset allows defining a set of alternative url for a given image, based on the viewport. The browser is then able to pick the most relevant image based on the browser’s viewport and screen density (e.g., 4k screens).

Let’s take this image of size 5184x3456px, weighting 4.7MB, and named stmalo-pool.png

If inserted naively in a page ([[image:stmalo-pool.png]]) the following html is produced

<img src="/xwiki/bin/download/ImageTest/WebHome/stmalo-pool.jpg">

The browser always loads 4.7MB (modulo the cache)

If inserted with a 1200px size ([[image:stmalo-pool.jpg||width="1200"]]) the following html is produced

<img src="/xwiki/bin/download/ImageTestWithSize/WebHome/stmalo-pool.jpg?width=800&amp;height=533&amp;rev=1.1" width="800">

The browser always load 35.1kb. This is already a real gain (mostly because I used a huge image as an example) but requires the editor to think of defining a image size.

Comes srcset where the following html would be produced:

<img src="/xwiki/bin/download/ImageSrcsetTest/WebHome/stmalo-pool.jpg?rev=1.1" srcset="/xwiki/bin/download/ImageSrcsetTest/WebHome/stmalo-pool.jpg?rev=1.1&amp;width=200 200w, /xwiki/bin/download/ImageSrcsetTest/WebHome/stmalo-pool.jpg?rev=1.1&amp;width=400 400w, /xwiki/bin/download/ImageSrcsetTest/WebHome/stmalo-pool.jpg?rev=1.1&amp;width=800 800w, /xwiki/bin/download/ImageSrcsetTest/WebHome/stmalo-pool.jpg?rev=1.1&amp;width=1600 1600w, /xwiki/bin/download/ImageSrcsetTest/WebHome/stmalo-pool.jpg?rev=1.1&amp;width=3200 3200w">

The src defines a set of alternative sizes for the image. Note that the set of defined sizes is to be discussed.

  • on my 4k screen, firefox picks the 3200w based on my viewport (1920px) and screen density of 2x. So only 172.80kB are downloaded instead of the initial 4.7MB for no human effort
  • if I resize my browser window to 800px, the 1600w image is used instead. For a size of 55.49kB.

Based on those experiment, I believe using srcset is a very efficient way to reduce the impact of images on network consumption while staying transparent from an end user point of view.

Before discussing implementation details, what do you think of the general idea?

Thanks!

Related pages:

1 Like

I have no experience with srcset (did not even know this existed) but this sounds good indeed, so +1 to pursue with this.

In general +1. I think the tricky question will be which sizes to generate. We might also lack the stored metadata what the native size of the image is, and parsing the image during rendering might also be a bad idea. We would also need to decide what to do if the user sets a certain image size. For screens with high DPI it might make sense to have bigger sizes available even if the image size itself is small.

That’s a good point. One option might be to compute and cache the image dimensions at upload time.

I think defining a list of predefined sizes, then generate the srcset for all size up to the width of the image (or up to the defined width if it exists) should already be a good first step.
For instance, based on the list of common sizes on Common Screen Resolutions in 2025: Mobile, Desktop & Tablet | BrowserStack we could define a default set (and provide a configuration):

  • 320
  • 768
  • 1280
  • 1980
  • 2560
  • 3840

Another option is to generate fragments like imageSize/2, imageSize/4, imageSize/8 and so on, up util the division is lower than a given threshold (e.g., 300px). So for an image of 2100px, the srcset would be 1050, 525, 262