Native lazy-loading (loading=lazy) not working even with flags enabled
Asked Answered
U

8

38

I am currently trying to update my Website using the new loading="lazy" attribute as shown here: https://web.dev/native-lazy-loading

As seen in the video, everything works as expected, but compared with my waterfall diagram in chrome, it doesn't.

How it looks: chrome developer tools

How it should look:

chrome developer tools

This is how its implemented:

<img class="has-border" src="https://andreramoncombucket.s3.amazonaws.com/static/assets/img/work/personal-website/pw_full.jpg" style="object-fit: cover;" alt="..." loading="lazy">
Undersea answered 2/9, 2019 at 7:52 Comment(3)
Did you resolve this?Inpatient
I'm experiencing the same issue.Aubigny
I am experiencing the same thing. Oddly, if I remove my stylesheet completely, lazy loading works as expected. I am curious if you might see the same behavior. EDIT: Turns out my page was not long enough to cause any images to be deferred. I tried on mobile, and it was work as expected.Wicklund
C
53

I had a similar issue when trying to implement it.

I use Chrome by default and it was not working. When I tested it in Firefox, it did work. That made me think it was a browser problem.

After digging in a bit more, I found out the "problem" for my case. It might be the same probably for many others.

It turns out Chrome is more impatient than Firefox when loading images tagged as lazy. That means it loads the images much earlier, so an image will not be loaded when it appears at the screen but earlier than that. Firefox, on the other side, is loading the images almost when they are about to be shown at the screen.

The images I was testing were below the fold, but the page was not very long, so Chrome was loading the images anyway.

When I tried it in a much longer article, the images that were deep down the article did load lazily in Chrome as well.

Hope this helps!

Coryden answered 18/5, 2020 at 10:11 Comment(4)
From my experimentation, seems that 3200px is about what chrome considers to be "below the fold" for lazy loading purposes.Ascham
On second though, it looks like it's a little more complicated than just a fixed pixel distance web.dev/native-lazy-loading/#load-in-distance-thresholdAscham
I tested and this answer is true, the image way below the screen viewport is loaded, the detail of the pixel treshold is described in this link: web.dev/browser-level-image-lazy-loading Chrome also will change threshold depending on the connection client are usingConvertible
Also you can't change the pixel viewing threshold seemingly... web.dev/browser-level-image-lazy-loading/…Semipostal
R
27

I had a similar problem, and after some research, I found the solution:

Just need to add width and height to the IMG tag, this is because the browser needs to know the size of the element before applying lazy loading.

Your code:

<img class="has-border" src="..." style="object-fit: cover;" alt="..." loading="lazy">

Your code after adding width and height:

<img class="has-border" src="..." style="object-fit: cover;" alt="..." loading="lazy" width="200px" height="200px">

Another alternative is using inline style:

<img class="has-border" src="..." style="object-fit:cover; height:200px; width:200px;" alt="..." loading="lazy">

Take into consideration I just randomly set the dimensions of the IMG tag to 200px. You can find more information on this web.dev article

hope it helps 👍

Religiose answered 16/5, 2021 at 1:2 Comment(0)
C
9

There is currently a bug in Firefox: The loading="lazy" attribute has no effect, if it is placed after the src attribute.

The fix is simple: place the loading attribute before the src attribute.

Working example:

<img
  loading="lazy"
  src=...
/>

The following will not work in Firefox - images will be loaded immediately (but works in Chrome):

<img
  src=...
  loading="lazy"
/>
Cabana answered 15/5, 2023 at 9:40 Comment(2)
That's it, thank you. BTW this bug looks super ridiculous :(Agnesagnese
are you sure its a bug? it fixed it for me on chromeJasper
I
4

I have the worst reason it wasn't working - I forgot to add the width and height attributes (they were instead added as styles in my broken code)

Incommensurate answered 15/9, 2020 at 21:45 Comment(1)
this can be a reason since chrome needs to know the exact dimens of the picture to avoid jumps when the images loadUndersea
N
2

optionally if you dont want to change your image size use this

Original code

<img class="has-border" src="..." style="object-fit: cover;" alt="..." loading="lazy">

With working Lazy load with no size restrictions

<img class="has-border" src="..." style="object-fit: cover;" alt="..." loading="lazy" width="auto" height="100%">
Niue answered 17/6, 2022 at 13:24 Comment(0)
J
0

One possible fix is just to implement it yourself with an IntersectionObserver at the footer of your document.

const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    const img = entry.target;
    if (entry.intersectionRatio > 0) {
      img.setAttribute("src", img.getAttribute("data-src"));
      observer.unobserve(entry.target);
    }
  });
});

//Get images that aren't visible on load
const imgs = document.querySelectorAll("img").filter((img) => {
  const { top, left, bottom, right } = img.getBoundingClientRect();
  return (
    top >= 0 &&
    left >= 0 &&
    bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
    right <= (window.innerWidth || document.documentElement.clientWidth)
  );
});

imgs.forEach((elm) => {
  //Save src to data-src
  elm.setAttribute("data-src", elm.getAttribute("src"));
  //Set src to single invisible base64 pixel to minimize jank
  elm.setAttribute(
    "src",
    "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==",
  );
  //Observe the element when it scrolls into the viewport
  observer.observe(elm);
});

Make sure you do it in the footer with a SYNCHRONOUS script tag. If you wait for DOMContentLoaded or the like, some of the images will have already been requested. E.g.

<html>
<body>
  Your body content, including images...
  <script>
     //PUT YOUR CODE HERE
  </script>
  </body>
</html>

Notice there are no attributes on the script. If your script tag has a defer or async attribute on it or is of type='module' the javascript won't execute until the image downloads have already begun.

Janaye answered 8/11, 2022 at 22:2 Comment(0)
S
0

It could be because of cache.

If you see here lazy-img in the Network tab that means everything is fine.

You can test on a private window if you want just to double check.

enter image description here

Sanmiguel answered 4/2, 2023 at 0:2 Comment(0)
C
-6

The image should be positioned as "relative" in style.

Conquistador answered 2/9, 2021 at 14:6 Comment(1)
Please provide additional details in your answer. As it's currently written, it's hard to understand your solution.Backlash

© 2022 - 2024 — McMap. All rights reserved.