2

I'm running a page through Google's Page Speed Analyzer and for mobile, it's telling me I should download the proper size images. I know the viewport size, but I don't know the width of the slot because we are using a responsive layout. I've looked at the documentation and a bunch of examples and none of them are using what I think should be the correct image.

The Network tab of developer tools is showing we are downloading about.webp for mobile and not either of the smaller images (200px or 400px). Even when changing the device in Chrome to a smaller viewport width, it still downloads about.webp.

What is the correct HTML for a picture element to get Page Speed Analyzer to use the appropriate image?

Below is my picture element. Thanks!

<div class="row"><div class="col-md-3">
    <picture>
        <source type="image/webp" 
            sizes="(max-width: 200px) 200px,
              (max-width: 400px) 400px,
              (max-width: 1500px) 1500px" 
            srcset="//cdn.storyboardthat.com/site-images/articles/education/about-sbt-w200.webp 200w,
//cdn.storyboardthat.com/site-images/articles/education/about-sbt-w400.webp 400w, 
//cdn.storyboardthat.com/site-images/articles/education/about-sbt.webp 1500w">
        <source type="image/png" 
            sizes="(max-width: 200px) 200px, 
              (max-width: 400px) 400px, 
              (max-width: 1500px) 1500px" 
            srcset="//cdn.storyboardthat.com/site-images/articles/education/about-sbt-w200.png 200w, 
//cdn.storyboardthat.com/site-images/articles/education/about-sbt-w400.png 400w, 
//cdn.storyboardthat.com/site-images/articles/education/about-sbt.png 1500w">
            <img src="//cdn.storyboardthat.com/site-images/articles/education/about-sbt.png" 
              alt="Storyboard That" 
              title="Storyboard That" 
              class="lazyload " 
              style="max-width:100%;height:auto;" 
              width="1500" height="400" loading="lazy"> 
    </picture>
</div>

John
  • 1
  • 13
  • 98
  • 177
Fongers
  • 155
  • 1
  • 1
  • 9
  • Add a relevant working sample of your code, rather than just pasting the code. – Abhishek Jain Nov 30 '20 at 20:00
  • Does the above change to the HTML you have added still throw an error for you @fongers as I believe the changes you have made will now allow a browser to select an image that is appropriate and will have fixed the problem you initially had. The 800w image will more than likely get selected by a browser due to the DPI explanation below as that is now close enough to 960px width to be used. If the changes have fixed the problem could you please revert the question as otherwise no answers will make sense. – GrahamTheDev Dec 11 '20 at 18:47
  • @GrahamRitchie I've removed the additional images (300, 600, 800px) because you are correct, with those additional image sizes, it was downloading the 800px one correctly. – Fongers Dec 12 '20 at 22:17
  • Glad you got it sorted, it is a bit weird still using the picture element, I am sure somewhere the actual decision tree code that browsers use is available as I would be intrigued what "tollerance" there is on an image or if it just picks the closest one. – GrahamTheDev Dec 13 '20 at 12:13
  • Exactly! I saw in another thread somewhere that the browser guess-timates the size of the slot the image goes in then looks at it's sources for the next size up. The documentation on it is absolutely horrible. – Fongers Dec 13 '20 at 17:05

2 Answers2

7

You have forgotten about Device Pixel Ratio (DPR).

You see the <picture> element basically says to browsers "here are a few options to choose from, I have indicated my preference but it is up to you to decide which image you think is best".

As you haven't specified a DPR preference the browser is using the following logic:

"Ok so I have 3 images to choose from, what is my current DPR? Oh I have DPR set to 3.

How big is the image at this screen width (320px)? Full screen width so I need a 320px image.

Ok so it is 320px * 3 DPR to ensure I have the highest quality image that matches my current display resolution.

So I need a 960px image minimum. My options are 200, 400 or 1500, I better choose the 1500 image and down sample it."

So how do I control pixel density decisions?

You can specify pixel density with 1x, 2x, 4x etc. For example:

<img src="default.webp"
srcset="hiddef.webp 2x, heighestdef.webp 4x"
alt="Image description">

However with how you have currently structured your picture element it won't quite work as you can't combine image 200w with image 2x to do image 200w 2x.

If you want to keep the same image at all DPIs then you would specify that image 3 times.

<img src="default.webp"
srcset="default.webp 2x, default.webp 4x"
alt="Image description">

Otherwise if you want the browser to change the image automatically based on DPR just leave your <picture> element as it is.

GrahamTheDev
  • 22,724
  • 2
  • 32
  • 64
0

I see that the code snippet you have used is incorrect, refer this:

<picture>
  <source media="(max-width:200px)" srcset="about-w200.webp">
  <source media="(max-width:400px)" srcset="about-w400.webp">
  <img src="about-sbt.webp alt="About" style="width:auto;">
</picture> 

A working reference link

Abhishek Jain
  • 630
  • 6
  • 26
  • I've done my googling and research and have found this example you posted. At the same time, there are many more examples of the `srcset` attribute for the `source` tag having multiple files listed. What, then, is the technical difference between the format you listed above and the format I'm asking about? Thanks! – Fongers Dec 01 '20 at 15:24