Cumulative Layout Shift (CLS) is a Core Web Vitals metric calculated by summing all layout shifts that aren’t caused by user interaction. CLS calculates the proportion of the viewport that was impacted by layout shifts and the movement distance of the elements that were moved.
In 2021, Cumulative Layout Shift became a Google ranking factor as part of Core Web Vitals and the Google Page Experience update.
What’s a good CLS score?
A CLS score can be as low as 0 for fully static pages and gets higher the more layout shifts occur on the page.
The lower your score, the more stable your layout is. Official CLS scores used by Google’s performance tools are as follows:
- Good – CLS below 0.1,
- Needs improvement – CLS between 0.1 and 0.25,
- Poor – CLS above 0.25.
Google recommends that you keep your CLS score under 0.1.
Does your CLS score affect your SEO?
CLS became a ranking factor in June 2021 when Google’s Page Experience Update started rolling out. That means your CLS score (together with Largest Contentful Paint and First Input Delay metrics) now affects your SEO. While it’s likely to be a very minor factor, your CLS score (along with the other Web Vitals) may reflect on the traffic you get from Google and other search engines.
Moreover, CLS correlates with user behavior metrics. While Google claims it doesn’t use metrics like dwell time or bounce rate for ranking purposes, other search engines, like Bing, admit using those metrics in their ranking algorithms.
For these reasons, optimizing CLS should definitely take priority in your SEO strategy.
Why you should worry about Cumulative Layout Shift
As I mentioned above – CLS is a ranking factor.
More importantly, though, a high CLS score means your users are having a bad time browsing your page.
Negative effects of multiple layout shifts span from mild annoyance to even accidentally purchasing the wrong product. It can result in bad reviews for the company and discourage users from returning to the site as well as repel new clients.
How CLS is calculated
There are two factors that go into CLS: impact fraction and distance fraction.
To calculate the impact fraction, you need to calculate the impact region first.
Impact region defines the area affected by the layout shift. Google identifies all affected elements and combines the original area with the shifted version, defining the impact region.
Impact region is usually a rectangle, but if you have multiple layout shifts – both horizontally and vertically – it can be a more complex shape.
Now let’s talk about the impact fraction.
To define the impact fraction, you divide the area of impact region by the area of the viewport (part of the page visible on the screen without scrolling down):
area of impact region / area of viewport = impact fraction
Google’s first version of CLS only consisted of the impact fraction. However, big elements might move only slightly, and large movements are more distracting than small ones. Having that in mind, this simple CLS calculation needed improvement.
For that reason, Google came up with using distance fraction.
To calculate the distance fraction, you first need to calculate the move distance.
Move distance defines the distance before and after the layout shift. It pretty much answers the question: how far did the shifted element move?
To calculate distance fraction, you need to divide max move distance by viewport height:
max move distance / viewport height = distance fraction
Calculating layout shift
The next step is to calculate the layout shift scores. Here you multiply impact fraction by distance fraction to get the layout shift score for a single animation frame:
impact fraction x distance fraction = layout shift score for a single animation frame
Calculating Cumulative Layout Shift
The current formula for calculating your page’s CLS score is different from the one originally proposed by Google.
Previously, to calculate Cumulative Layout Shift, you would take the layout shift scores for all animation frames and add those scores together.
Layout Shift Score 1 + Layout Shift Score 2 + … = Cumulative Layout Shift
However, this method turned out to be slightly “unfair” to long-lived Single Page Applications without a mechanism of hard navigation between specific pages of the application.
Google’s researchers decided to implement a mechanism of grouping layout shifts in session windows.
Session windows are essentially time frames within the lifecycle of your page, inside of which layout shifts are summarized.
When a layout shift happens on your page, a session window is opened. It can last for a maximum of 5 seconds but will close sooner if no layout shifts occur within 1 second from the previous shift.
Layout shifts are then summarized within session windows. Your final CLS score is the max score of a single session window – other session windows don’t influence your CLS.
To give you an example:
- Your page starts rendering.
- After 1s, a layout shift of 0.1 occurs.
- 0.5s later, another shift of 0.2 occurs.
- 2 seconds later, a shift of 0.25 occurs, and then the page is closed.
The two initial layout shifts occurred within the same session window, so we add the scores together.
The third layout shift occurred after 2 seconds, so it belongs in a separate session window. The previous session window closed one second after the second layout shift.
So in this scenario, your page’s final CLS score would be 0.1 + 0.2 = 0.3! The third layout shift doesn’t influence the final score.
How can this change in the score formula affect your scores? Google has an answer:
Since this update caps the CLS of a page, no page will have a worse score as a result of this change.
And based on our analysis, 55% of origins will not see a change in CLS at all at the 75th percentile. This is because their pages either do not currently have any layout shifts or the shifts they do have are already confined to a single session window.
The rest of the origins will see improved scores at the 75th percentile with this change. Most will only see a slight improvement, but about 3% will see their scores improve from having a “needs improvement” or “poor” rating to having a “good” rating. These pages tend to use infinite scrollers or have many slow UI updates, as described in our earlier post.source: web.dev
Other things you should know about CLS
Intentional layout changes
CLS ignores all layout shifts that appear within half a second from user input. It’s called the input exclusion window. This means that CLS measurement stops for 500ms after every user interaction with the site. So, if the layout change is intentional and caused by the user, it won’t affect your CLS.
Animations and layout shifts
Animations can cause layout shifts, but not all of them will be count towards your CLS score. Google ignores CSS transform changes – so if your animation uses transform property, it won’t affect your CLS.
Generating layout shifts
Usually, layout shifts happen while loading the page – but they can occur later as well and will contribute to your CLS score if they happen outside of the input exclusion window.
Layout shifts and content above the fold
CLS only counts shifts visible in the viewport. If something moves below the fold and the user does not see it, such a shift won’t affect CLS in the slightest.
How to measure Cumulative Layout Shift?
Since CLS can be measured both in a lab and during real user interactions, you can and should look at both your CLS lab score and your CLS Real User Data.
CLS – Lab Data
Lab Data means using tools to simulate the user’s experience. It’s exactly like lab testing – almost real, but in a controlled environment and the results only account for a small range of possible situations.
You can access your CLS lab data via the performance tools mentioned below.
CLS – Real User Data
Real User Data is data based on real user interactions. Gathered by Google and other third parties, it allows you to see the bigger picture. You can compare Real User Data with your lab results. For Google, the main source of Real User Data is Chrome User Experience Report, also known as CrUX.
CrUX data can be accessed via:
- Google’s BigQuery,
- Google Data Studio,
- PageSpeed Insights,
- CrUX API,
- Google Search Console (Core Web Vitals report).
What is causing Cumulative Layout Shift?
According to Google, the most common causes of high CLS are:
- Images without dimensions,
- Ads, embeds, and iframes without dimensions,
- Dynamically injected content,
- Web fonts causing FOIT/FOUT (Flash of Invisible Text and Flash of Unstyled Text),
- Actions waiting for a network response before updating the DOM.
How to improve your Cumulative Layout Shift
If your site is using fonts hosted online, they might be the main cause of FOIT (Flashes Of the Invisible Text) and FOUT (Flashes Of the Unstyled Text).
When the browser downloads the fonts from the server, it often displays blank space until the custom font loads. After downloading and displaying the font, the layout usually moves quite a lot. It’s called FOIT (Flashes Of the Invisible Text).
Another scenario occurs when the browser displays one of the system fonts until the custom one is downloaded. We call that FOUT (Flashes of The Unstyled Text). Since the system font may differ from the custom one, it may take up a different amount of space. Because of that, the layout of your site might move significantly after your custom font loads.
To avoid this, you can use font:display values such as auto, swap, block, fallback, and optional. For an even better result, you can also preload font files using <link rel=preload> for key fonts – this way they will be downloaded as a priority asset.
Including width and height elements for videos and images
In the old days of the Internet, web developers used to include width and height elements everywhere on the site. It looked like this:
<img src=”example.jpg” width=”800″ height=”300″ alt=”Example Image”>
This became less popular when responsive web design took over. Due to this new approach, developers started using CSS to resize images.
Good for them, but not so much for the users affected by CLS.
With this method, space is allocated only after the browser starts downloading the image. After all the images are displayed, the layout would move, causing unnecessary shifts.
A much better solution for resizing images is using an aspect ratio. It is the ratio of width to height (e.g., 16:9).
Using the aspect ratio allows the browser to calculate the space needed to display the image – and this way reduce the risk of layout shift.
If you’re dealing with responsive images, you can use srcset attribute. It allows you to set up several photo sizes and the browser to display the best possible size.
Wrong implementation of dynamically injected content
Dynamically injected content should never appear above content that’s already loaded. The only exception to this rule is when the change is caused by user interaction. As I mentioned before, such content won’t affect CLS if it’s loaded within 500ms after the interaction.
If you’re looking for more resources on optimizing your CLS, Google published a very informative guide to optimizing CLS – I strongly recommend it.
CLS might be less intuitive compared to other Core Web Vitals, but it’s a very useful score. It can help you diagnose why users are unhappy with your site and improve their experience.