0

I'm getting a low CLS (layout shift) score on google page speed test, and I figured out it is because of how my slider loads. When the page is loading (mostly on slow connections) the slider's images are all loaded below eachother, when the page is done loading and the javascript loads, only then are the rest of the images hidden and starts to slide.

I created the following slider from a tutorial. I have no idea how to solve this problem. I would think the best way would be to try and hide all the other images (except the first one) until the javascript is loaded. Is there a way to achieve this with javascript? Or is there a better solution

What would be the best way to approach this problem? Here is my slider's code:

var slideIndex = 0;
showSlides();

function showSlides() {
  var i;
  var slides = document.getElementsByClassName("single-slide");
  for (i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";
  }
  slideIndex++;
  if (slideIndex > slides.length) {slideIndex = 1}
  slides[slideIndex-1].style.display = "block";
  setTimeout(showSlides, 6000); 
} 
Shtarley
  • 313
  • 9
  • 22

2 Answers2

1

you have to put the display: none as default on your blocks, using for example css classes. If your javascript is at the end of the page (as it should be) the browser starts to load images before you put the display: none from javascript

ggirodda
  • 770
  • 7
  • 19
1

So you have a couple of issues with the way you are handling the "slider" (as at the moment from the code shown this wouldn't be a slider but just show images one after the other).

Problem one

The first is on initial page load as you have identified.

The images will all load in and then ultimately move the page around as they stack upon each other.

The simplest solution is to have some inline css in the <head> that hides all the slider images.

<head>
    <style>
        .single-slide{display: none}
    </style>
</head>

It must be inline otherwise the CSS could get applied too late and your slide will still show.

Then unhide them as needed similar to how you are doing it now.

This introduces another problem.

What happens when your first slide loads in? The image would then appear and you will get a massive layout shift.

Problem 2

Layout shift from when slides are added to the page.

The solution to this is also quite straight forward. You need to display your images in a wrapper where you can define the size and add overflow: hidden to ensure the size does not change if an image doesn't have the correct proportions.

Yet again this needs to be defined inline otherwise the wrapper will start with 0 height and width and then make the page jump around when your CSS loads.

So your page would roughly look like this:

<html>
    <head>
        <style>
            .single-slide{
                display: none
            }
            .wrapper{
                width: 100%; 
                height: 600px;
                overflow:hidden; 
            }
        </style>
    </head>
    <body>
        <div class="wrapper">
            <img class="single-slide"/>
            <img class="single-slide"/>
        </div>
    </body>
</html>

An additional problem not related to CLS

With your current slider you hide all the images and then add the new one, on a slower device this might end up with a very short time where no image is displayed.

Now CLS is not going to be affected if you put a fixed size wrapper on the page as suggested, but User Experience won't be great.

Instead add the new image over the top and then hide all the other images, this will ensure no white flashes.

GrahamTheDev
  • 22,724
  • 2
  • 32
  • 64