Open buildpath-ian opened 1 year ago
I'm also facing this issue. threshold
seems to simply be ignored, which leads to <iframe>
that are close to the fold to be loaded directly on the first page load, which causes Core Web Vitals TBT problems since a lot of third-party code ends up being downloaded without any user interaction.
Well... it seems that the problem was use_native
. You can see here that browser's native thresholds are pretty high (1250px). The solution I found was to use native loading only for images and use the library for iframes
to avoid loading tons of third-party code.
Thanks, @MtDalPizzol it makes sense.
Yes it you set use_native
you then delegate the lazy loading to the browser, losing most control on the loading via JavaScript.
The solution you found sounds very smart. Can I ask you to try using JS (not native) lazy loading also on the images and see if your Largest Contentful Paint further improves? I guess it will.
@verlok I could try that. But to be honest, I don't see how it would make LCP better. I feel like anything that needs "foreign" JS code will always perform worse than native browser functionality. Is there something I'm not aware of here? Also, in the Core Web Vitals docs, they repeatedly state that you should run as little JS as possible AND use native when available. On top of that, my largest element on page load is not lazily loaded. So, at least in my case, it doesn't seem necessary to do that.
By the way, to be clear: I'm using the library for both (images, and iframes), just with different configs:
import LazyLoad from 'vanilla-lazyload'
export default function initLazyLoad () {
const lazyImages = new LazyLoad({
elements_selector: 'img.lazy',
use_native: true
});
const lazyIframes = new LazyLoad({
elements_selector: 'iframe.lazy',
threshold: 600
});
}
@MtDalPizzol
But to be honest, I don't see how it would make LCP better.
I will explain in a second..
I feel like anything that needs "foreign" JS code will always perform worse than native browser functionality.
Correct.
On top of that, my largest element on page load is not lazily loaded.
Awesome. This is indeed a best practice.
If you take all of the a above, you may agree with me that a) the image causing your LCP won't be delayed if you load every other image else using JS, but b) if you use native lazy loading, images that are just below the fold are loaded as soon as the page loads, meaning while the LCP image is loading, meaning slowing its loading down.
This would be visible especially on slower connection.
You don't have trust me, just try it and test it using webpagetest.org, on both fast and slow connections.
@verlok
b) if you use native lazy loading, images that are just below the fold are loaded as soon as the page loads, meaning while the LCP image is loading, meaning slowing its loading down.
This makes A LOT of sense. I'll surely give this a try. Thank you so much for the tip.
My only concern with this, is that Core Web Vitals are a tricky beast to handle. We're working hard, trying to get ready for the new INP metric that comes into play in march 2024, and since TBT can affect INP, I'm a little worried that leaving image handling to JS might affect INP due to potentially triggering long tasks during the page lifecycle.
Thanks for sharing, @MtDalPizzol I'm a web performance consultant (check andreaverlicchi.eu) so I perfectly understand what you say.
I cN tell you that my lazy load script doesn't run any long task, it just watches the elements using the IntersectionObserver API and when it's time, it copies one attribute on another.
@verlok
I cN tell you that my lazy load script doesn't run any long task, it just watches the elements using the IntersectionObserver API and when it's time, it copies one attribute on another.
Sure! In fact, that was the reason I switched from lazysizes
to vanilla-lazyload
. lazysizes
was triggering long tasks when I inspected my pages on the Performance tab.
I'll go ahead and implement your suggestions! Thanks a lot, again!
PS: already following on X and reading the articles on the site. :relaxed:
Hi,
Please see the issue shown on video here: https://www.loom.com/share/d172a32f5f6a447a99ecd2942a9daeb9
My init is:
ll = new LazyLoad({ // Assign the callbacks defined above callback_enter: callback_enter, callback_exit: callback_exit, callback_cancel: callback_cancel, callback_loading: callback_loading, callback_loaded: callback_loaded, callback_error: callback_error, callback_finish: callback_finish, elements_selector: "iframe", threshold: 300, });
I also have the callbacks from your demos set up, so I can see that it's loading without me scrolling at all. It seems to do it twice somehow. I don't know what to think except that something on my page may be tricking the Intersection Observer somehow.