Have you ever visited a website and was about to click a link to an article, and then… the layout suddenly moves, an ad appears, and somehow instead of clicking on the article you wanted to read, you click on the useless ad?
That sudden movement on the page is called the layout shift.
Keep reading to learn how to measure it on your website and optimize it.
Given the emphasis placed on the User Experience by the web developer community, it’s staggering that so many popular websites do nothing to stabilize their layouts, stuffing their pages with interstitials, banners, and intrusive ads that ruin the experience for their users.
For Google, User Experience is clearly a priority, and various Chrome team members have been talking about layout shift for years now.
That’s why Google made Cumulative Layout Shift (CLS) a part of Core Web Vitals – a set of performance metrics that attempt to quantify the User Experience.
What is Cumulative Layout Shift?
Cumulative Layout Shift is a performance metric that measures the visual stability of content. It calculates how the layout of a page changes throughout its lifecycle.
A CLS score can be as low as 0 for fully static pages and gets higher the more elements of a page are moving around.
What’s a good CLS score?
The lower the CLS 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.
Is Cumulative Layout Shift a ranking factor?
CLS isn’t currently a ranking factor. But it is one of Google’s Core Web Vitals and will become a ranking factor in 2021 when Google’s Page Experience Update rolls out.
Why you should worry about Cumulative Layout Shift
As I mentioned above – CLS is going to be a ranking factor soon.
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.
High CLS correlates with other metrics relevant to UX, such as bounce rate, session length, and rage clicks.
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
Finally, to calculate Cumulative Layout Shift, you 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
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
Using font:display values and link rel=preload
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 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.