8

I'm using Bootstrap with Responsive Images. I want to optimize load times by offering multiple image sizes to browsers. According to this article, a plain approach with srcset like this is good for letting the browser pick the optimal image size:

<img src="small.jpg" srcset="medium.jpg 1000w, large.jpg 2000w" alt="yah">

My problem is that combining this with the Bootstrap img-responsive class, a large size picture gets loaded even when only a small one is needed.

Code example here: Bootply . Use Chrome for testing, it has built-in support for srcset support! (Some other browsers would need picturefill.js to recognize it.)

If you copy the source of the image (or look in Chrome Developer Tools in the Network tab), you can see that the 750 width version gets loaded, and resized to a small image, even though there are smaller versions that would be optimal to use. (The same thing happens in IE and Firefox if the picturefill JS is loaded to support img srcset.)

What am I doing wrong?

Andrew
  • 817
  • 2
  • 10
  • 21

1 Answers1

9

You need to use the sizes attribute to tell the browser which width the image will have in your design, otherwise it defaults to 100vw (full viewport).

<img sizes="(max-width: 480px) calc(100vw - 10px), 480px" src="small.jpg" srcset="small.jpg 600w, medium.jpg 1000w, large.jpg 2000w" alt="yah" />

In case you can set the width in CSS, you can also use lazySizes to automatically calculate the sizes for you.

With lazySizes:

<img data-sizes="auto" class="lazyload" data-srcset="small.jpg 600w, medium.jpg 1000w, large.jpg 2000w" alt="yah" />
alexander farkas
  • 13,754
  • 4
  • 40
  • 41
  • Thank you @alexanderfarkas, lazysizes is excellent. For the others who run into a similar issue: I missed the fact before that skipping the `sizes` attribute altogether by itself does not mean that the browsers will calculate the final size of the image in time. They just assume they're 100vw (full device width). It may be a good guess for a mobile version. But if you're using Bootstrap to display some images in smaller sizes in the desktop version too (eg. many columns, small image in one of them), you NEED to set `sizes` one way or another to avoid serving the biggest version of the image. – Andrew Feb 10 '15 at 09:31
  • Thanks... i'm finally resolve it with this answer and with this set of `sizes=" (min-width 40em) 576px, (min-width 64em) 720px, (min-width 72em) 960px, 100vw"` – equiman May 06 '15 at 16:51
  • The sizes attribute is not perfect. Even if I measure the img element and width of the html element, calculate the exact percentage and apply this as vw, the browser loads the larger image file, eventhough the smaller one would still fit without stretching. – imrek Jun 29 '15 at 15:12
  • The only possible explanation I see is that the width of the scrollbar is added to the viewport width when the 'sizes' value is interpreted by the browser. The scrollbar is not part of the html document, though. – imrek Jun 29 '15 at 15:17
  • The vw is computed for the hole viewport including a "possible" scrollbar. At the time the browser starts to select/download an image, he doesn't even know whether the document needs a scrollbar or not. – alexander farkas Jun 29 '15 at 17:02
  • Should edit the answer to incorporate Equiman's comment of 5 May 15 @ 16:51 as that fixed the sizes issue for me as well. – Merovex Jan 27 '18 at 17:01
  • Sharing just an additional portion of information's related to responsive images and unexpected loading. Even though the attribute sizes and srcset is set correctly. https://www.sitelint.com/blog/why-is-the-image-srcset-attribute-not-working-on-the-page/ – Cezary Tomczyk Feb 21 '23 at 16:48