It's February 2020 now and I'm pleased to report that Google Chrome, Microsoft Edge (the Chromium-based Edge), and Mozilla Firefox all support the new loading="lazy" attribute. The only modern browser hold-out is Apple's Safari (both iOS Safari and macOS Safari) but they've recently finished adding it to Safari's codebase, so I expect it will be released sometime this year.
It's February 2024 now and I'm pleased to report that all web-browsers today have supported <img loading="lazy" /> since January 2022.
The loading="lazy" attribute is only for the <img /> element (and not <picture>) but remember that the <picture> element does not represent the actual replaced-content, the <img /> element does (i.e. the image that users see is always rendered by the <img /> element, the <picture> element just means that the browser can change the <img src="" /> attribute. From the HTML5 spec as of February 2020 (emphasis mine):
The picture element is somewhat different from the similar-looking video and audio elements. While all of them contain source elements, the source element's src attribute has no meaning when the element is nested within a picture element, and the resource selection algorithm is different. Also, the picture element itself does not display anything; it merely provides a context for its contained img element that enables it to choose from multiple URLs.
So doing this should just work:
<picture>
<source media="(min-width: 45em)" srcset="large.jpg" />
<source media="(min-width: 18em)" srcset="med.jpg" />
<source src="small.jpg" />
<img src="small.jpg" alt="Photo of a turboencabulator" loading="lazy" />
</picture>
Note that the <picture> element does not have any width or height attribute of its own; instead the width and height attributes should be applied to the child <source> and <img> elements:
The width and height attributes on img, iframe, embed, object, video, source when the parent is a picture element [...] may be specified to give the dimensions of the visual content of the element (the width and height respectively, relative to the nominal direction of the output medium), in CSS pixels.
[...]
The two attributes must be omitted if the resource in question does not have both an intrinsic width and an intrinsic height.
So if you want all <source> images to be rendered as 500px by 500px then apply the size to the <img> element only (and don't forget the alt="" text for vision-impaired users, it's even a legal requirement in many cases):
<picture>
<source media="(min-width: 45em)" srcset="large.jpg" />
<source media="(min-width: 18em)" srcset="med.jpg" />
<source src="small.jpg" />
<img src="small.jpg" alt="Photo of a turboencabulator" loading="lazy" width="500" height="500" />
</picture>
<pictures>(and why that would not work)?<source>elements in a picture, instead of using thesrcattribute of an img.<picture>tag, but most likely appropriate image is loaded during html parsing (like they do currently for<img>tag), so the only way to stop it is to usedata-srcattribute instead ofsrcin<source>tag. But even in this case there are some issues, so in LazyLoadXT we started to use<br>tag instead of<source>: ressio.github.io/lazy-load-xt/demo/picture.htm (I don't remember exactly what was the issue with<source>tag, but that way didn't work in some browsers, while<br>did)<br>tag!