Closed Bug 1542784 (lazyload) Opened 3 years ago Closed 2 years ago

Support <img loading="lazy"> lazy-loading

Categories

(Core :: DOM: Core & HTML, enhancement)

67 Branch
enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla75
Webcompat Priority revisit
Tracking Status
firefox75 --- fixed

People

(Reporter: jmcbray, Assigned: hiro)

References

(Depends on 3 open bugs, Blocks 3 open bugs)

Details

(Keywords: dev-doc-complete, Whiteboard: [webcompat][layout:backlog:2020q1], [wptsync upstream])

Attachments

(9 files)

47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0

Steps to reproduce:

Chrome is adding support for lazy loading images and iframes, as specified here: https://github.com/scott-little/lazyload/.

Actual results:

Firefox does not support this syntax, and I could not find an existing bug requesting it.

Expected results:

Firefox should also implement this. Currently, lazy-loading images not only requires using JavaScript, it also requires writing your HTML in such a way that your images will not be loaded at all with JavaScript disabled. Putting image lazy-loading in the browser's handling of the <img> tag makes it possible to provide this in a more robust way, lower down the web stack - you can confidently use the <img loading="lazy"> syntax and know that the fallback to eager loading will work in all browsers.

Type: defect → enhancement

Bug report for the old "lazyload" attribute: https://bugzilla.mozilla.org/show_bug.cgi?id=947427

There isn't yet a reasonable spec for lazyload, but it does feel like a good addition to the web platform.

Keywords: dev-doc-needed

WHATWG Pull Request for "loading" attribute: https://github.com/whatwg/html/pull/3752

Flags: webcompat?
Whiteboard: [webcompat]

Migrating Webcompat whiteboard priorities to project flags. See bug 1547409.

Webcompat Priority: --- → ?

See bug 1547409. Migrating whiteboard priority tags to program flags.

Component: Untriaged → HTML: Parser
Product: Firefox → Core

Starting with Chrome 76, you'll be able to use the new loading attribute to lazy-load resources without the need to write custom lazy-loading code or use a separate JavaScript library. — https://web.dev/native-lazy-loading

(In reply to Wellington Torrejais da Silva from comment #7)

Not working: https://mathiasbynens.be/demo/img-loading-lazy

It's not working, because this feature isn't implemented yet. It's not even standardized yet. See the issue Joshua linked to. But I'm guess once the discussion there has settled and the feature is in the specification, Mozilla will prioritize this.

Sebastian

If the spec for this is well thought-through, complete and has gone through the proper process.... then we should do this ASAP. It gives Authors simple tools for greatly improving the performance of their sites, and will result in Firefox being faster.

I'm also getting many, many requests for this feature — and questions about when we are shipping it. Authors are eager for it.

(In reply to Jen Simmons [:jensimmons] from comment #9)

If the spec for this is well thought-through, complete and has gone through the proper process....

I haven't reviewed this on that level.

then we should do this ASAP. It gives Authors simple tools for greatly improving the performance of their sites, and will result in Firefox being faster.

I'm also getting many, many requests for this feature — and questions about when we are shipping it. Authors are eager for it.

So for the HTML: Parser component, this request is just turning off prefetching for <img> if there's an attribute loading whose value is lazy, right? Or is there more for the HTML parser to do? (And then the rest of the feature goes under Layout.)

Flags: needinfo?(jensimmons)

FWIW, the HTML PR isn't in a good shape (yet) and I'm also not sure there's adequate test coverage. See https://github.com/mozilla/standards-positions/issues/151 for Mozilla's overall position.

Duplicate of this bug: 947427

This shouldn't be in "HTML: Parser" at all. A tiny fraction of the relevant work will happen there...

Status: UNCONFIRMED → NEW
Component: HTML: Parser → DOM: Core & HTML
Ever confirmed: true
Webcompat Priority: ? → revisit
Depends on: 1594672
No longer depends on: 1594672
Flags: needinfo?(jensimmons)
Whiteboard: [webcompat] → [webcompat][layout:backlog:2020q1]
Alias: lazyload
Blocks: 1611387
Assignee: nobody → hikezoe.birchill
Status: NEW → ASSIGNED
Depends on: 1612243
Blocks: 1612649
Blocks: 1612780

So that it can accept a callback function implemented in C++ for lazy-loading.

Depends on D61435

Note that there are 3 web platform tests which still fail with this
implementation.

/loading/lazyload/original-base-url-applied-tentative.html
/loading/lazyload/original-crossorigin-applied-tentative.sub.html
/loading/lazyload/original-referrer-policy-applied-tentative.sub.html

These tests are supposed to expect that changing base url doesn't affect
lazy-load images once after its target url was resolved. That's true as per the
spec.

As per "updating-the-image-data" [1] in the spec, the step for resolving URL is
done in the step 11;

  1. Parse selected source, relative to the element's node document, and let
    urlString be the resulting URL string. If that is not successful,

Then in the step 22;

  1. If the will lazy load image steps given the img return true, then run
    these steps:

So after the step 11, the resolved URL will never be changed even if it's for
lazy-load images. Wheares our current image load implementation is not
compliant with this spec. Once after we implement spec compliant in bug
1076583, these tests should pass as it is.

Depends on D61437

There are two variation of the tests.

  1. The image element gets visible by scrolling the iframe's scrollport.
  2. The image element gets visible by scrolling the parent scroll container of the iframe

Depends on D61438

Blocks: 1613277
Attachment #9124023 - Attachment description: Bug 1542784 - Add a mochitest to make sure loading="lazy" is not honored in script disable iframe. r?emilio → Bug 1542784 - Add a wpt to make sure loading="lazy" is not honored in script disable iframe. r?emilio
Attachment #9124024 - Attachment description: Bug 1542784 - Reset the deferred load flag when the deferred image element moves into script disabled document. r?emilio → Bug 1542784 - Add a wpt when the deferred image element moves into script disabled document. r?emilio
Blocks: 1613611
Pushed by hikezoe.birchill@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/7c714a35e683
Annotate bug number for tests affected by an open issue [1] for lazy-loading. r=emilio
https://hg.mozilla.org/integration/autoland/rev/c6419c6e50be
Add loading attribute to the HTML parser. r=hsivonen
https://hg.mozilla.org/integration/autoland/rev/7def7a454580
Stop speculative image load for lazy load images. r=hsivonen
https://hg.mozilla.org/integration/autoland/rev/03c1c36d300c
Make DOMIntersectionObserver::mCallback Variant. r=emilio,bzbarsky
https://hg.mozilla.org/integration/autoland/rev/63cb9dca2a0d
Use nsIRequest::LOAD_BACKGROUND for lazy-load image elements. r=hsivonen
https://hg.mozilla.org/integration/autoland/rev/e27886fc6a2a
Implement lazy loading for images. r=emilio,hsivonen
https://hg.mozilla.org/integration/autoland/rev/738e2a3729cf
Add tests for lazy-load images in cross origin iframes. r=emilio
https://hg.mozilla.org/integration/autoland/rev/aaf6810da7b9
Add a wpt to make sure loading="lazy" is not honored in script disable iframe. r=emilio
https://hg.mozilla.org/integration/autoland/rev/f2f84d35d5cc
Add a wpt when the deferred image element moves into script disabled document. r=emilio
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/21768 for changes under testing/web-platform/tests
Whiteboard: [webcompat][layout:backlog:2020q1] → [webcompat][layout:backlog:2020q1], [wptsync upstream]
Upstream web-platform-tests status checks passed, PR will merge once commit reaches central.
Upstream PR merged by moz-wptsync-bot

(In reply to Pulsebot from comment #24)

https://hg.mozilla.org/integration/autoland/rev/c6419c6e50be
Add loading attribute to the HTML parser. r=hsivonen

Landed in the htmlparser repo:
https://github.com/validator/htmlparser/commit/0ee4b8afe8c4866c32597d847838e20e87075ddb

No longer blocks: 1611387
Regressions: 1615522
See Also: → 1622090

Documentation updates:

When JavaScript is disabled (either by disabling it from the DevTools settings or by setting javascript.enabled to false in about:config), lazy-loading does not work, and all the images of the page are immediately loaded.

Is this behaviour intended? I didn’t find anything related to this scenario in the WHATWG spec.

As an author, I’ve been surprised by this. Seeing no relationship between the unavailability of JavaScript and the loading of HTML images by the browser, I would expect loading="lazy" to be honoured regardless of the ability to run JavaScript in the page, so that users could still benefit from the performance improvements coming from the attribute.

(In reply to michael from comment #31)

When JavaScript is disabled (either by disabling it from the DevTools settings or by setting javascript.enabled to false in about:config), lazy-loading does not work, and all the images of the page are immediately loaded.

Is this behaviour intended? I didn’t find anything related to this scenario in the WHATWG spec.

Yes, that's intentional. https://whatpr.org/html/3752/images.html#updating-the-image-data

(In reply to Hiroyuki Ikezoe (:hiro) from comment #32)

Yes, that's intentional. https://whatpr.org/html/3752/images.html#updating-the-image-data

Oh, so this is an anti-tracking measure. This makes sense. Thank you!

Do you think this reliance on JavaScript availability is worth being mentioned in the docs on MDN?

Indeed, it would be nice to have a note about the script case in the doc. :sheppy, would you mind adding a note there?

Flags: needinfo?(eshepherd)

I have added the note. Thank you for providing that info!

Personally, while it makes sense to disable it to prevent tracking, I think this feature deserved a separate option to control it and not be bound to whether scripting is enabled, but that's an issue for the specification. For what it's worth, I've created one at https://github.com/whatwg/html/issues/5495 asking about that.

Sebastian

Flags: needinfo?(eshepherd)
See Also: → 1483280
Depends on: 1648064
Depends on: 1650677

When reloading a page while the scroll position is already below an image with loading="lazy", the image is not loaded in FF 83.0.

To reproduce:

  • Visit a page with an <img loading="lazy"> image
  • Scroll down so that the image is not in the viewport
  • Reload (F5)
  • Scroll up to the image

=> the image is not loaded

I need to correct myself.
It seems to affect only <picture><img loading="lazy"></picture> since this example works fine: https://lazy-loading.firebaseapp.com/lazy_loading_native.html

<picture>
  <source media="(min-width: 40em)" srcset="big.jpg 1x, big-hd.jpg 2x">
  <source srcset="small.jpg 1x, small-hd.jpg 2x">
  <img src="fallback.jpg" loading="lazy">
</picture>

When reloading a page while the scroll position is already below an image with loading="lazy", the image is not loaded

Why would you expect and image that is outside the viewport of the first render, be it below or above?

It seems to affect only <picture><img loading="lazy"></picture> since this example works fine: https://lazy-loading.firebaseapp.com/lazy_loading_native.html

If I scroll to the bottom, reload and very quickly scroll up, I can see the pictures loading lazily, I guess it is just much faster then on the first load as some might be cached!? A hard refresh, which clears the images from the cache also resets my scroll position.

(In reply to Albert Scheiner [:alberts] from comment #38)

Why would you expect and image that is outside the viewport of the first render, be it below or above?

It is outside (above) the viewport when loading the page, but then scrolling to show the image does trigger loading it.

If I scroll to the bottom, reload and very quickly scroll up, I can see the pictures loading lazily, I guess it is just much faster then on the first load as some might be cached!? A hard refresh, which clears the images from the cache also resets my scroll position.

This is an example where it is working as intended for me. It just uses <img loading="lazy">. Even using the dev tools (-> network) to disable the cache yields correct results for me.

On a test page with <picture><img loading="lazy"></picture> it is not working in the mentioned condition.

Here is an example in the wild where it is not working for even with enabled cache: https://www.schempp-hirth.com/en/sailplanes.

Please file a new bug about that, feel free to CC me on it. But that page is a bit weird because it requires you to open stuff using JS, so when you refresh the page contents are not the same.

Depends on: 1687358
Depends on: 1692350
You need to log in before you can comment on or make changes to this bug.