Table of Contents

About

A layout shift occurs when the rendering of the web page shifts / move element from their current position.

Causes

Image

For instance:

  • without the knowledge of the target ratio (via the height and width attribute of an image, the browser can't reserve space for the image
  • it download the image calculate the space needed for the image
  • recalculate the layout
  • and shifts element around to be able to put the image

That's what's called a layout shift

1)

Solution:

  • Set the correct image ratio on the image tag with the height and width attribute

Style

When you change a layout css property after page load (the first rendering), you will also create a layout shift.

Solution: If you want to change two layout property at the same time, you should use the window.requestAnimationFrame function to avoid a layout shift.

Example with a dynamic correction of a fixed top header such as the Bootstrap navbar where:

  • we add the fixed-top class that set the position to fixed
  • and correct it with a padding on the body.
window.requestAnimationFrame(function() {
    let fixedNavbar = document.querySelector(".navbar[data-type=\"fixed-top\"]")
    fixedNavbar.classList.add("fixed-top");
    let offsetHeight = fixedNavbar.offsetHeight;
    document.body.style.setProperty("padding-top",offsetHeight+"px");
});

Measurement

Occurences: Devtool

In the devtool, layout shift can be seen

  • in the performance tab:
    • click the start and reload page (Ctrl+Shift+E)
    • stop it when the page has finish loaded
    • check the experience row.

Layout Shift Devtool Performance

  • in the rendering tool where you can see the shifted region and and the web core vitals.

Devtool Chorme Rendering Layout Shift

Cumulative layout shift

The Cumulative layout shift or CLS is a web core vital metrics that groups all layout shift during page load.

  • The devtool can also add an overlay. See the web core vital for more information.

Devtool Chrome Web Core Vital Overlay

  • A library can report back the cumulative layout shift (or CLS) measurement. See the example below

Calculation Example with Perfume

Example with perfume

  • The element that we are going to shift
<button>Click to see the cumulative value</button>
  • Simulate a layout shift
setTimeout(function(){
        let button = document.querySelector("button");
        button.style.display = "block";
        button.style.marginLeft= "auto";
        button.style.marginRight= "auto";
        button.style.width= "fit-content";
}
,2000);
  • The engine
new Perfume({
  analyticsTracker: options => {
    const { metricName, data, eventProperties, navigatorInformation, vitalsScore, } = options;
    switch (metricName) {
      case 'cls':
        console.log('cumulativeLayoutShift value: '+data);
        break;
      case 'clsFinal':
        console.log('cumulativeLayoutShiftFinal: '+data);
        break;
    }
  },
});
  • Output: