All Collections
FAQ's and Troubleshooting
Cumulative Layout Shift - CLS
Cumulative Layout Shift - CLS
Eduard Ungureanu avatar
Written by Eduard Ungureanu
Updated over a week ago

Table of Contents:

What is CLS?

Cumulative Layout Shift (CLS) is a user-centric metric for measuring visual stability because it helps quantify how often users experience unexpected layout shifts—a low CLS helps ensure that the page is delightful.

Unexpected page content movement usually happens because resources are loaded asynchronously. DOM elements get dynamically added to the page above existing content. The culprit might be an image or video with unknown dimensions, a font that renders larger or smaller than its fallback, or a third-party ad or widget that dynamically resizes itself.

CLS measures the total of all individual layout shift scores for every unexpected layout shift that occurs during the page's entire lifespan.

A layout shift occurs whenever a visible element changes its position from one rendered frame to the next.

What is a good CLS score?

To provide a good user experience, sites should strive to have a CLS score of 0.1 or less. To ensure you're hitting this target for most of your users, a good threshold to measure is the 75th percentile of page loads, segmented across mobile and desktop devices.

Why does CLS happen in the first place?

Let's see what actually happens on any given HTML page while the user interacts with it:

  1. A page load begins when a user selects a hyperlink, submits a form, or types a URL in a browser. This is also referred to as the initial request or the navigation start. The user's action sends a request across the network to the web application server.

  2. The request reaches the application for processing. (The request may take some time to start being processed. This could be the result of request queuing, or it could be other factors.)

  3. The app finishes processing and sends an HTML response back across the network to the user's browser. This is sometimes referred to as response start or first byte.

  4. The user's browser receives the HTML response and starts to process the Document Object Model or DOM.

  5. The DOM finishes loading; this point is known as DOM ready. Using the DOM, the user's browser starts to render the page.

  6. The page finishes rendering in the user's browser and the window load event fires.

The CLS will happen most of the time between steps 4, 5, and 6. A lot is going on since the initial request was made until the page is fully visible in the browser. This whole process can be faster or slower, the speed depending on many factors, the most important ones being:

  • the server speed;

  • the server resources;

  • the server optimization - cache, gzip compression, header expiration dates, and so on;

  • the number of active plugins - any active plugin will "fight" over server resources and will create additional HTTP requests, which might delay the loading time.

What can be done to avoid or reduce CLS on a web page?

A simple answer will be to reserve space for the layout elements: Sections/Rows/Modules.

Reserving space can be done by setting a min-height value for each of the elements that create the CLS. The min-height property's value should be equal to the final height's value of a particular element - Section/Row/Module.

Real-world example

Considering this page. The structure of that page is composed of the following elements:

  1. Theme Builder Header Template

  2. Page Content - Fullwidth Slider Module

  3. Theme Builder Footer Template

The Theme Builder Header Template contains a Normal Section with a Row that has a layout of 3 columns:

  • the first column contains an Image Module

  • the second column contains the Menu Module

  • the third column contains the Social Media Follow Module

The Page Content contains a Fullwidth Section which also contains the Fullwidth Slider Module

The Theme Builder Footer Template contains a Normal section, which is set to be Fixed at the bottom in the page's layout with a Row that has a 2 columns layout:

  • the first column contains 3 Text Modules

  • the second column contains 2 Text Modules and the Social Media Follow Module

If the example page is checked in Google Page Speed Insights, it has a CLS score of 0.249 - which is not bad, but it can be improved even further.

Google Page Speed Insights will also provide information about the elements in that page's layout that create the CLS. Scrolling down on the Report page and expanding the Avoid large layout shifts option, exact information is being provided

In this case, the elements that create CLS (even if that is really low) are:

  • the Fullwidth Slider Module

  • the Row inside the Header Template layout

  • the Row inside the Footer Template layout

The easier thing we can do would be to reserve the space for each of the marked elements, generally speaking setting a min-height value for the container element should suffice.

Note: A container element is an element that contains all other elements. EG: for the Menu Module, the container element can be either the Row or the Section.

On the example page, setting the min-height value for the Section that contains all the Header Template elements to be 63px and also setting the Section of the Page Layout (that contains the Fullwidth Slider Module) to be 737px, will decrease the initial CSL from 0.025 to 0.001:

This is a new page in which the same Header Template, Footer Template, and page content is used, but with elements having a min-height value set.

Find out which values should be used for each element that creates CLS

To find out which is the value that can be used as the min-height value Developer Tools can be used.

Using the same page example, on the Front end, clicking anywhere on the page and choosing Inspect from the contextual menu will open the Developers Tools. Inspecting any element will provide details, including the Height of that particular element:

In this case, I was inspecting the Header's Section. As soon as I hover over it gets highlighted on the page, the width (1920px) and height (63px) are provided. The min-height value for that Section it can be set to 63px.

Testing the results

Another option would be to install and configure a cache plugin. There are few good choices out there (free and premium). In this example, I used the WP Rocket cache plugin. You can also use the WP Fastest Cache plugin which is free. The New CLS score for the demo page, after installing the Cache plugin and configuring it to work on the specific server used here, is 0.001

Besides, setting the correct values for the elements that create CLS for mobile also helps to reduce the CLS to 0 for mobile devices while using a cache plugin:

Did this answer your question?