One of my websites has a really bad LCP, 4.6. I realized that without active lazyload my images, the LCP is 2.0 . The TCB increased by using lazyload, too. So Im thinking it must be my bad JS-Skills, so could give me anyone of you a hint?
My actual code:
let lazyImages = [...document.querySelectorAll('img[data-src],iframe[data-src],div[data-bg],header[data-bg]')];
let inAdvance = 300;
function lazyLoad() {
lazyImages.forEach(image => {
if ( !image.classList.contains( 'lazyloaded' ) && !image.classList.contains( 'none' ) && image.getBoundingClientRect().top <= window.innerHeight + inAdvance && image.getBoundingClientRect().bottom >= 0) {
if( image.hasAttribute( 'data-src' ) ){
image.src = image.dataset.src;
}
if( image.hasAttribute( 'data-bg' ) ){
image.setAttribute( 'style', 'background-image:url( ' + image.dataset.bg + ' );' );
}
image.classList.add('lazyloaded');
//image.onload = () => image.classList.add('lazyloaded');
}
})
}
window.addEventListener( 'scroll', lazyLoad, {passive: true} );
window.addEventListener( 'resize', lazyLoad, {passive: true} );
window.addEventListener( 'slick', lazyLoad, {passive: true} );
I've already tried a replacement with observer, but there wasnt any improvement by tcb or lcp.
This tends to be an implementation issue.
LCP measures when the largest paint appears on the page. If you use lazy loading and the images are visible "above the fold" (without scrolling) and they are the largest paint on the page then they will be reported as LCP. This can also be the case if just the top of an image is showing.
Now if you are lazy loading them and your JavaScript is loaded late in the page load order it means that the images will get downloaded later, increasing your LCP time.
Don't lazy load images that appear "above the fold" just use a standard <img>
or <picture>
element.
That's it! Lazy load everything that is out of view when the page loads as the performance gains are worth it (as well as improving bandwidth usage etc.).
TBT is looking for a "quiet time" on the CPU to determine when the main work on the page is done.
What the test also does is scroll the page to the bottom.
Because of this your function is probably being called multiple times in quick succession and bottle-necking the CPU (bearing in mind that the CPU has a 4x slowdown applied for mobile scoring to simulate a real world mobile device with less powerful CPU.)
Because you have the event listener set to fire on 'scroll'
it is being fired multiple times and I assume you have multiple images on the page.
One thing you could do is to change your actual function so it isn't having to do as many loops each time.
i.e. once you have set your image src
or background style
, remove that item from your lazyImages
list. This reduces the amount of items that need checking when the page is scrolled and will result in better performance.
Also just check how often slick
slider causes your function to be called as that could be causing performance issues also.
The above may not fix your TBT but is good practice anyway.