Is it possible to reduce the amount of sources in this picture element?

72 Views Asked by At

I’m writing a Laravel Blade component that will print a <picture/> element with different sources. Based on the layout and on the availability of images there can be different configurations, but in any case I think that the resulting markup is very long, so I’m asking if there can be a shorter way of doing the same thing.

This is the starting image:

<img src="img_home_desk.jpg" width="1340" height="777"/>

For this image I also have avif and webp versions, so I have to add a surrounding picture element with the two alternative sources:

<picture>
  <source srcset="img_home_desk.avif" type="image/avif">
  <source srcset="img_home_desk.webp" type="image/webp">
  <img src="img_home_desk.jpg" width="1340" height="777"/>
</picture>

Now I want a smaller image to be shown for non retina displays, so I add the 1x version:

<picture>
  <source
    srcset="img_home_desk.avif 2x, img_home_desk_670.avif"
    type="image/avif"
  >
  <source
    srcset="img_home_desk.webp 2x, img_home_desk_670.webp"
    type="image/webp"
  >
  <img src="img_home_desk.jpg" width="1340" height="777"/>
</picture>

Now if I want a different image for the mobile viewport, I have to add two more sources. For the small images I don’t have the retina versions, but those images have a different ratio, so I will specify the width and height in the sources (see: For responsive images with different aspect ratios, what's a good way to minimize Cumulative Layout Shift?)

<picture>
  <source
    srcset="img_home_desk.avif 2x, img_home_desk_670.avif"
    media="(min-width: 992px)"
    type="image/avif"
  >
  <source
    srcset="img_home_desk.webp 2x, img_home_desk_670.webp"
    media="(min-width: 992px)"
    type="image/webp"
  >
  <source
    srcset="img_home_desk_750.avif"
    media="(max-width: 991px)"
    type="image/avif"
    width="750"
    height="440"
  >
  <source
     srcset="img_home_desk_750.webp"
     media="(max-width: 991px)"
     type="image/webp"
     width="750"
     height="440"
    >
   <img src="img_home_desk.jpg" width="1340" height="777"/>
</picture>

At this point I thought I was done, but if I remember correctly Lighthouse was still complaining that the images were too large for some viewports. So I added two intermediate images for both the mobile and the desktop viewports.

Please note that for every new image size I have two formats, so now we have 4 new source elements:

<picture>
  <source
    srcset="img_home_desk.avif 2x, img_home_desk_670.avif"
    media="(min-width: 1200px)"
    type="image/avif"
  >
  <source
    srcset="img_home_desk.webp 2x, img_home_desk_670.webp"
    media="(min-width: 1200px)"
    type="image/webp"
  >
  <source
    srcset="img_home_desk_1140.avif 2x, img_home_desk_570.avif"
    media="(min-width: 992px)"
    type="image/avif"
  >
  <source
    srcset="img_home_desk_1140.webp 2x, img_home_desk_570.webp"
    media="(min-width: 992px)"
    type="image/webp"
  >
  <source
    srcset="img_home_desk_750.avif"
    media="(min-width: 413px)"
    type="image/avif"
    width="750"
    height="440"
  >
  <source
    srcset="img_home_desk_750.webp"
    media="(min-width: 413px)"
    type="image/webp"
    width="750"
    height="440"
  >
  <source
    srcset="img_home_desk_600.avif"
    media="(max-width: 412px)"
    type="image/avif"
    width="750"
    height="440"
  >
  <source
    srcset="img_home_desk_600.webp"
    media="(max-width: 412px)"
    type="image/webp"
    width="750"
    height="440"
  >
  <img src="img_home_desk.jpg" width="1340" height="777"/>
</picture>

Please note that I have simplified the srcs of the images to make my point clearer, but in reality the images are generated by a CMS (Contentful) by passing some parameters (for example img_home_desk.jpg?fm=webp&w=764), so in order to make this work we don’t need to actually create all those variations: in the end when the browser computes the correct image to download there will only be one request to the server.

So my question is: do you think that there is a shorter way of expressing this? I’ve seen that it’s possible to list different sources in the srcset property, but they can’t be mixed with the 2x density descriptors (as explained here: https://www.debugbear.com/blog/responsive-images) so maybe it’s not possible to create a shorter syntax for my use case (where there can be 2x versions for every source), but I’d like to have some suggestions on how this syntax can be improved.

0

There are 0 best solutions below