Page MenuHomePhabricator

Enable native image lazy loading on desktop
Open, LowPublic

Description

Summary as of June 2026:

MobileFrontend shipped a JavaScript-based implementation for lazy loading images in 2016.

In 2019, the Performance Team implemented a native solution in MediaWiki core as a progressive enhancement (T230897). This feature flag remains disabled by default as of 2026 due to unresolved issues with printing (including save/export to PDF).

Upstream bugs with print mode:

In 2020, the JavaScript-based solution in MobileFrontend was rewritten using IntersectionObserver to avoid slow synchronous event handlers while scrolling (especially impactful on KaiOS). See T246838 and T246767.

In 2024, @TheDJ ported the native solution in MediaWiki core from legacy Parser to a Parsoid transform (limited to MobileFrontend and Parsoid-enabled wikis) as part of T230812. This is enabled in production e.g if you manually enable Parsoid on a page https://en.wikipedia.org/wiki/Canada?useformat=mobile&useparsoid=1.

Chrome fixed the print issue for desktop in 2022, but it appears to remain unresolved for Chrome Mobile (Android). It also remains unresolved in Safari, although for desktop Safari there's a workaround that TheDJ found (ref).

Fast-forward a few years and as of 2026, Parsoid is enabled on a lot of wikis. And while it is not yet enabled on enwiki as a whole, it is enabled for 100% of mobile web pageviews since April 2026 (T424880). As a result, native image lazy loading is enabled for all of these as well. But, we still haven't enabled it for desktop (i.e. the current task).

Note that the Parsoid implementation remains local to MobileFrontend and there are tasks to bring this into Parsoid itself and/or MediaWiki core, which is effectively a prerequisite for this task because enabilng $wgNativeImageLazyLoading would not ineffective for desktop on Parsoid-enabled wikis (T324158).

Original 2016 task description by @Jdlrobson:

After the success of https://blog.wikimedia.org/2016/09/19/mobile-web-improvements/ we should explore making the same changes in core (feature flagged of course) as the savings to be had are equally big (if not larger - there is an opportunity to save the cost of running Wikipedia if the bytes savings are significant).
Most of the code can easily be upstreamed with the exception of the MobileFormatter logic which would now be able to run in the parser.

Related Objects

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

@Jdlrobson Can you flesh out the description with some of the technical implementation details? It's on @ovasileva's radar for the product side.

If you are on a slow connection, this is absolutely horrible UX, especially on desktop.

On mobile it makes sense:

  • Mobile connections are often relatively fast, so there's less overall visible latency associated with each request
  • Data caps are quite common for mobile connections, so you want to try to avoid downloading extra stuff to avoid using up people's data
  • Screen size is small and people also tend to go to more things more quickly without necessarily scrolling down, so there's less point downloading everything anyway

For mobile, the data caps alone would be reason enough, but that just doesn't apply to most desktop use, nor are the usage patterns the same, either.

It's basically a trade-off in terms of experience: do you want to sit through a somewhat longer download process at the start, but then have everything right there, or do you want to have to wait constantly every time you scroll down? Given that the latter actually adds more overhead due to multiple individual requests, and also more opportunities for an individual request to fail (something that is particularly common on bad connections), and generally no way to re-try the failed request short of reloading the page, which then requires all the other requests to go again.

From a UX standpoint, I would strongly recommend against this.

Jdlrobson lowered the priority of this task from Medium to Low.Jun 15 2017, 9:25 PM

It's basically a trade-off in terms of experience: do you want to sit through a somewhat longer download process at the start, but then have everything right there, or do you want to have to wait constantly every time you scroll down?

Just to clarify, images are not render-blocking resources. The only render-blocking resource is the main stylesheet. Once that arrives, the browser will progressively render article content and images as they come in. On slow connections, the article will likely be readable in its entirely, while some of the images are still missing (white box reserved). This is browser default behaviour.

In addition, HTTP/2 request multiplexing also assigns a relatively lower priority to images in all major browsers. Which means images already get deprioritized, compared to article content and styles.

While there is a "longer download process at the start", this happens in the background while reading, not something users knowingly wait for.

This is to say that, bandwidth aside, this isn't even a trade-off. Without lazy-loading you already get the best of both. (Fast first render and shorter delays when reading later sections.)

With such reports on native image lazy loading: https://twitter.com/TheRealNooshu/status/1163827485076799489?s=20 and given how simple the implementation is (DOM element attributes), I think we should go ahead with native image lazy loading on desktop.

One thing we'll need to test is the browser's print feature (which we now promote prominently from the sidebar as well). In particular, to figure a way to force-load them (as mobile currently does), or to block on upstream browsers fixing this on their end if they haven't already.

We also need to warn developers and tech community to inform them that any code that uses the window "load" event, might stop working. As it might no longer wait for these images, and thus can no longer be used to know when it is safe to access dimension information (e.g. in mediaviewer, core gallery/slideshow, and gadgets).

Dimension information is exposed in attributes for thumbnails, for Media Viewer's sake. I don't think that Media Viewer relies on the load event to wait for anything, as users can click on thumbnails before the load event.

I'm surprised that printing is affected (verified on this demo: https://mathiasbynens.be/demo/img-loading-lazy), seems like a spec or implementation bug. Indeed, there is a Chrome bug for it: https://bugs.chromium.org/p/chromium/issues/detail?id=875403

As for workaround, there is an onbeforeprint event, but we would have to load the missing images as sync XHRs during that event, wouldn't we? Seems like this would cause a browser freeze.

The print feature in the sidebar seems to rely on a different version of the page, though (with different HTML), for which we could conceivably disable image lazy loading. The issue remains for users who invoke the browser's print feature directly themselves on an article.

@Gilles The printable=yes url linked in the sidebar for "Print this page" is a fallback for no-js and context/middle click only. By default, "Print this page" triggers the browser's own print feature for the current browser view.

At the time of T24256, we didn't find any use cases for the printable mode, so instead we promote the browser's own way of making a printable view - with the help of a few @media print style rules. I'm not sure why we kept the fallback, other than perhaps to reduce the amount of work done at once (so we could verify the hypothesis first), and perhaps for the convenience of IE6-8 users as these browsers don't support @media print and would not look as good in printed form without them.

See also:

The fallback could be removed by making the link only visible for .client-js (without FOUC).

IMHO we should first investigate the problems with lazy image loading on mobile. In particular, I think essential images that are part of the main text flow of reading should be preloaded before they become visible. Often I try to read Wikipedia articles for instance in the subway, the text seems to be all right but without the essential images (like math formula) I can't make sense of the articles. I took the following screenshot today in the subway. It took almost a minute until the images did appear.

Screenshot_20190823-154829.jpg (1,080×2,340 px, 545 KB)

If these images were prefetched at the station (with good signal) or loaded together with the text the reading experience would have been much better.

I'm surprised that printing is affected (verified on this demo: https://mathiasbynens.be/demo/img-loading-lazy), seems like a spec or implementation bug. Indeed, there is a Chrome bug for it: https://bugs.chromium.org/p/chromium/issues/detail?id=875403

As for workaround, there is an onbeforeprint event, but we would have to load the missing images as sync XHRs during that event, wouldn't we? Seems like this would cause a browser freeze.

Yeh that seems like an oversight to me. Looks like others have run into this too as I got some recent activity on an old bug for mobile's print problems - https://github.com/whatwg/html/issues/2532#issuecomment-524109565 - is this something we could flag in the w3c?

It's an HTML standard, so now handled by WHATWG, not the W3C. But I'm not sure that there's a proper standard proposal for the loading attribute yet anyway.

I think it would be really interesting to try this on one wiki for a short while and measure what kind of win it will make in number of bytes. If we can show the numbers, it would be easier to talk to Chrome to put prio on the solution for printing?

Using https://codepen.io/Krinkle/pen/GRBjXRG (via temporary debug URL, so no framing) checked the latest browsers.

In Chrome, the lazy images correctly don't load (using Devtools Network as validation), and when printing via menu or via JS button, it loads them, and the resulting preview includes the images on the last page indeed. Nice!

In Safari, it remains broken as per https://bugs.webkit.org/show_bug.cgi?id=224547.

Screenshot 2023-01-04 at 18.44.14.png (1,852×1,331 px, 221 KB)

We've been tracking this since last year at https://github.com/whatwg/html/issues/6581 in conversation also via our W3C WebPerf participation. We're now waiting for Apple or other WebKit contribitors to implement, and then for Apple to release it.

Using https://codepen.io/Krinkle/pen/GRBjXRG (via temporary debug URL, so no framing) checked the latest browsers.

In Chrome, the lazy images correctly don't load (using Devtools Network as validation), and when printing via menu or via JS button, it loads them, and the resulting preview includes the images on the last page indeed. Nice!

FYI: For documentation purposes this Chrome fix was done in jan 2022. https://bugs.chromium.org/p/chromium/issues/detail?id=875403

See also improvement done in February as part of T266155: Frequent "Error: 429, Too Many Requests" errors on pages with many (>50) thumbnails in https://gerrit.wikimedia.org/r/c/mediawiki/core/+/883570

Today I noticed that we also have the images in [[Special:Log/upload]], which is apparently using yet another pager, which could use that same lazy load optimisation that I made for T266155

Today I noticed that we also have the images in [[Special:Log/upload]], which is apparently using yet another pager, which could use that same lazy load optimisation that I made for T266155

This is apparently a commons gadget, so no core functionality.
[edit]: This gadget was improved to set loading=lazy.

I was talking to @cscott about this today.
@CDanis enabling lazy loaded images on desktop in Parsoid would reduce requests for thumbnails across the site, reduces HTML processing time on mobile (which currently uses DOM parsing) and be an improvement for users so would likely also be popular with SRE. Currently the mobile version of Parsoid supports native lazy loading via MobileFrontend.

Untagging epic as using native lazy loading is a solved problem for mobile (and can be reused for desktop).

I was talking to @cscott about this today.
@CDanis enabling lazy loaded images on desktop in Parsoid would reduce requests for thumbnails across the site, reduces HTML processing time on mobile (which currently uses DOM parsing) and be an improvement for users so would likely also be popular with SRE. Currently the mobile version of Parsoid supports native lazy loading via MobileFrontend.

I'm not sure if lazy loading content when printing from Safari is fixed yet. I haven't tested it for a while (and the testcase has since disappeared).

Regardless, I don't think we should hold off on deploying Parsoid with lazy loading, even if it were to break Safari printing. The pageview share of Safari+print combined is small enough and people can use Chrome as a workaround when they do encounter this problem

An updated history:

History

MobileFrontend shipped a JavaScript-based implementation for lazy loading images in 2016.

In 2019, the Performance Team implemented a native solution in MediaWiki core as a progressive enhancement (T230897). This feature flag remains disabled by default as of 2026 due to unresolved issues with printing (including save/export to PDF).

Upstream bugs with print mode:

In 2020, the JavaScript-based solution in MobileFrontend was rewritten using IntersectionObserver to avoid slow synchronous event handlers while scrolling (especially impactful on KaiOS). See T246838 and T246767.

In 2024, @TheDJ ported the native solution in MediaWiki core from legacy Parser to a Parsoid transform (limited to MobileFrontend and Parsoid-enabled wikis) as part of T230812. This is enabled in production e.g if you manually enable Parsoid on a page https://en.wikipedia.org/wiki/Canada?useformat=mobile&useparsoid=1.

Chrome fixed the print issue for desktop in 2022, but it appears to remain unresolved for Chrome Mobile (Android). It also remains unresolved in Safari, although for desktop Safari there's a workaround that TheDJ found (ref).

Fast-forward a few years and as of 2026, Parsoid is enabled on a lot of wikis. And while it is not yet enabled on enwiki as a whole, it is enabled for 100% of mobile web pageviews since April 2026 (T424880). As a result, native image lazy loading is enabled for all of these as well. But, we still haven't enabled it for desktop (i.e. the current task).

Note that the Parsoid implementation remains local to MobileFrontend and there are tasks to bring this into Parsoid itself and/or MediaWiki core, which is effectively a prerequisite for this task because enabilng $wgNativeImageLazyLoading would not ineffective for desktop on Parsoid-enabled wikis (T324158).

Krinkle renamed this task from Desktop MediaWiki should be able to lazy load images to Enable native image lazy loading on desktop.Thu, Jun 25, 2:52 AM
Krinkle updated the task description. (Show Details)

I think we should just add my hack to the site javascript, and add a link to each printed page pointing to the browsers bug tickets ;)