Page MenuHomePhabricator

Use native image lazy loading on mobile site
Open, Stalled, LowPublic

Description

This landed in Chrome 76, which is now the stable version: https://www.chromestatus.com/feature/5645767347798016

The description shows how elaborate this first implementation is, taking into account effective network conditions to adapt the amount of lazy-loading:

The distance threshold after which the deferred content will start loading-in depends on factors including the current effective connection type, and whether Lite mode is enabled. The distance is chosen so that the deferred content almost always finishes loading by the time it becomes visible.

I've verified this behaviour using a demo page linked from the work-in-progress spec: https://scalable-loading-contribs.firebaseapp.com/test.html and it works as advertised.

This adaptive behaviour is more advanced than our current homemade JS-based solution. Additionally, having the browser do it natively will get rid of processing overhead (see T225946).

Support for native image lazy loading can be detected via:

if ('loading' in HTMLImageElement.prototype) { }

Event Timeline

Gilles renamed this task from Use native lazy loading to Use native image lazy loading.Aug 20 2019, 3:11 PM
Gilles renamed this task from Use native image lazy loading to Use native image lazy loading on mobile site.Aug 21 2019, 8:35 AM
Jdlrobson subscribed.

Unless I'm missing something, I don't see any benefit of using native lazy loading right now since we still need to rewrite the DOM for browsers where native lazy image loading is not available and that could get a bit messy supporting both modes.

<noscript>
  <img alt="" src="//upload.wikimedia.org/wikipedia/commons/thumb/9/99/Emanuel_Gottlieb_Leutze_-_Columbus_Before_the_Queen.JPG/300px-Emanuel_Gottlieb_Leutze_-_Columbus_Before_the_Queen.JPG" decoding="async" width="300" height="224" class="thumbimage" data-file-width="1536" data-file-height="1147">
</noscript>
<span class="lazy-image-placeholder" style="width: 300px;height: 224px;" data-src="//upload.wikimedia.org/wikipedia/commons/thumb/9/99/Emanuel_Gottlieb_Leutze_-_Columbus_Before_the_Queen.JPG/300px-Emanuel_Gottlieb_Leutze_-_Columbus_Before_the_Queen.JPG" data-alt="" data-width="300" data-height="224" data-class="thumbimage"></span>
</a>

That said, possibly it might be neater to replace the lazy-image-placeholder such that it's more inline with the spec and serve an img tag with attribute lazy. I don't think we're going to have time to look at this ourselves this year given our big project relates to refreshing desktop but seems enticing when browser support is better!

It would be nice if we could just do the switch when we have X amount on mobile traffic that supports it, but we would still regress performance (and increase download) for users with older browser (probably users that needs it the most)? So I think we need to live with the both solutions side by side. But not saying we should implement it now :)

It seems that its coming in WebKit soonish https://bugs.webkit.org/show_bug.cgi?id=196698#c80.

@Jdlrobson would be cool to also look into it on desktop when you do the new projects? There we could have clean start and just use it for browsers that supports it.

Jdlrobson changed the task status from Open to Stalled.Jul 24 2020, 2:54 PM

Until there is a way to ensure images show up in the print version and until there is better browser support we can't consider this.

Until there is a way to ensure images show up in the print version and until there is better browser support we can't consider this.

Yeah... browsers really botched it with print/PDF/offline support for lazy loading. This is a blocker for desktop as well, where that might be an even more prominent use case (T230897, T148047).

I did some testing on how our current JS-based lazy-loading of images works on mobile today (Chrome desktop, Firefox, desktop, and iOS 14). I'm curious if native image loading on mobile might be worth re-exploring for mobile in light of some of the following.

enwiki-mobile, Print to PDF: Mobile Safari on iOSSafari on MacFirefoxChrome
IMG_4488.PNG (1×750 px, 320 KB)
enwiki-mobile print Safari desktop.png (1×1 px, 248 KB)
Screenshot 2023-01-23 at 15.47.18.png (1×1 px, 358 KB)
Screenshot 2023-01-23 at 15.47.01.png (1×1 px, 417 KB)

The current JS-based approach:

  • .. also doesn't work for print I confirmed this again just now in Firefox and Chrome on desktop browsing en.m.wikipedia.org and no images in the PDF for me. This is tracked for mobile at T162414: User should be alerted when lazy loaded images haven't loaded in printed version of articles.
  • .. doesn't have a great fallback T261609: Allow older browsers without IntersectionObserver support to opt out of lazy loaded images.
  • .. is not very robust or fault tolerant, perf issue T136693: Make lazy loading images resilient.
  • .. renders nothing until and unless the image is downloaded and rendered competedly, or has explicilty failed. E.g. if the image downloads very slowly over 10 seconds of if the last few bytes won't arrive for some reason, nothing renders.
  • .. rendering is not only initiated by JS but also delayed through JS main thread code afterwards. This is due to the late-starting JS-triggered animation. After the image is downloaded and rendered by the browser, it still remains invisible due to CSS hiding it until the JavaScript main thread is idle again to process MobileFrontend's img-onload callback which then queues the animation to start on the next frame, and after another 300ms of animations, the image is visible. This is significantly slower than e.g. a CSS transition that starts unconditionally on img insertion from the start of the download. That way, if the image downloads fast, it'll be part of the fade. If it downloads slow, then the fade has invisibly completed already and it can continue to render natively. (Noting that CSS will continue on its own thread)

While desktop remains blocked on improving Print to PDF, on mobile this doesn't appear to be a blocker since it was broken years ago already.