Cumulative Layout Shift (CLS) is a Core Web Vitals metric used to measure how much the content of a webpage moves around (shifts) unexpectedly while the page is loading.
- It is classified as an official Core Web Vitals metric. Only CLS, LCP, and INP are official metrics that you must pass or fail. Every other metric is a notable metric, something that might impact them.
- Why is it important? Because CLS has a huge impact on the user experience. Nothing is more annoying than trying to click or read something and things start shifting around.
This article is based on a livestream, if you prefer to watch, you can view the entire presentation here:
What is good CLS?
According to Google, they want you to have a CLS score of 0.1 or less. They calculate it with this formula: Impact fraction * distance fraction = CLS
- Impact Fraction: The percentage of the viewport’s width or height that the shifted content occupies, indicating how much visual impact the shift has on the user.
- Distance Fraction: Measures how far the content has moved relative to the viewport size, capturing the extent of the shift’s disruption to the user’s experience.
They use the 75th percentile to determine where you stand. 75% of the visits/crawls need to meet the “good” threshold for you to get that classification. Also, as of 2023, CLS makes up 25% of the overall total score in PageSpeed Insights. See the Lighthouse Scoring Calculator.
How to measure CLS
There are many different tools and Chrome extensions you can use to measure CLS. Here are a few of my favorites (in order of preference) that I use on a regular basis:
- PageSpeed Insights (PSI)
- DebugBear ⭐
- WebPageTest ⭐
- Chrome DevTools
- CLS Debugger tool
- Layout Shift GIF Generator tool
- Web Vitals Chrome extension
Google Search Console is also a great tool to notify you of all the URLs where you might be failing CLS. I always recommend setting up a profile. The sooner you have more data the better.
PSI and real-user data
It’s important to understand the difference between lab data and real-user data. Lab data is at the bottom of the report under the “Diagnose performance issues” section. This top section is real-user data. It’s collected over an average of 28 days as users hit your site and are recorded for Core Web Vitals. Or rather, they are the only metrics that really matter. But remember, it’s always delayed.
Also, pay attention to this tab to see if there is enough data for your individual URL. Otherwise, the origin (average) of your site is shown.
Common sources of CLS and debugging tips
The best way to troubleshoot CLS is to launch a staging/dev site and go back to the basics (disabling plugins, switching back to default core theme, etc.). Most hosting providers have a staging or dev site feature; otherwise, I recommend InstaWP.
Always test multiple times. CLS is one of those things that can vary quite a bit. If you’re seeing consistent CLS over multiple tests, you can pretty much assume it needs fixing. Keep an eye on the real-user data.
These are the most common sources of CLS that I’ve seen:
- Bad theme code (or setting misconfigured). Many popular page builders actually have CLS problems.
- Dynamic JS in plugins that load things above the fold: sliders, reviews, etc.
- Optimization plugins. Yes, optimization plugins are a very common source of CLS. If you want to rule out Perfmatters, for example, we have our query strings, so you can easily test with optimizations off without having to disable the entire plugin. Example: https://domain.com/?perfmattersoff
- Web fonts loading late
- Not specifying dimensions on images
- Google Ads
- Animations
Important: Optimization plugins aren’t meant to be a quick fix for all CLS issues. Usually, you need to fix the root of the issue. And sometimes this means reaching out to the developer of the theme, page builder, plugin, etc.
Debugging “Avoid large layout shifts”
If you’ve tried debugging CLS in PageSpeed Insights, then you’re probably familiar with their warning “avoid large layout shifts.” While they show you some of the worst elements where the CLS is happening, there’s rarely enough information to track down the exact source of the problem.
This is where I turn to DebugBear and WebPageTest. They provide excellent tools to help track down the CLS. It shows you an image of the biggest shift.
- They show you thumbnails for each layout shift, starting with the worst ones.
- They have video records, and you can click frame by frame (similar to throttling, but easier)..
Improving CLS: Image width and height
One of the first things to check when debugging CLS is to ensure you are adding width and height to all of your images. If you aren’t, you’ll see the following warning in PageSpeed Insights: “Image elements do not have explicit width and height.”
Many themes and page builders should add this, but I still see the warning all the time. We have a feature in our Perfmatters plugin to automatically add missing image dimensions. <img src="image.png" width="340" height="160" alt="my awesome alt" />
You can also use the CSS property aspect-ratio. However, typically this is done by your theme or plugin.
Improving CLS: Lazy loading and Dynamic JS
At first glance, you might think lazy loading is a big factor in CLS. However, this isn’t actually the case. The reason is that lazy loaders, such as the one in our Perfmatters plugin, grab the image dimensions and put placeholders behind the scenes to reserve that space. This prevents a shift from happening.
Now it’s always good to ensure you aren’t lazy loading something by accident above the fold. But in general, image dimensions (as we went over in the previous slide) are much more important than lazy loading in terms of CLS.
However, dynamic content loading, which you might mistake for lazy loading, can lead to CLS. Consider a slider or review plugin positioned above the fold. If its images initially appear, then vanish momentarily before reappearing, this might not be lazy loading but rather the result of JavaScript dynamically re-rendering elements. The height of the document changes, and you have to wait for JavaScript to load and calculate the size of the element. This process causes a visual shift. Sliders, review testimonial plugins, carousels, etc., are all pretty common sources of CLS.
In many of these cases, you need to chat with the developer of that solution to fix the issue. However, another quick solution would be to move it below the fold. For example, perhaps you are OK with your testimonials showing slightly farther down the page.
Improving CLS: Preloading/swapping Fonts
Fonts are a very common source of CLS. These days, many themes and plugins utilize a display option called “swap” for performance reasons. This means they swap temporarily back to system fonts. The problem is this can sometimes cause a shift.
Here are some ways to prevent/fix CLS from fonts:
- Preload your fonts. You can do this in our Perfmatters plugin.
- Host your fonts locally. The faster the load time, the better. You can do this in our Perfmatters plugin.
- Use modern .woff2 files. Get rid of .woff and .ttf.
- Limit the number of variations/subsets used.
- If you are less concerned with design, go with system fonts and fix it immediately. We use system fonts on perfmatters.io. However, there is always a tradeoff between design and performance.
Improving CLS: Working with Google Ads
Another common issue we see is Google Ads. For example, if you simply use the “responsive ads” code from Google Adsense, this will shift right out of the box as it resizes for different devices.
The way to fix this is to reserve the space with placeholders, just like we do with image dimensions.
We typically recommend using plugins like Advanced Ads or Ad Inserter, as they already have systems in place to add predefined blocks. Or you could do this with some CSS and say an Element in GeneratePress.
Improving CLS: Avoid non-composited animations
The “Avoid non-composited animations” warning is basically saying that you’re using animations in a way that aren’t optimized for performance (or as smooth as they could be), and this results in layout shifts. The only way to really fix this is to reach out to the developer whose code is running the animation.
In a more technical explanation, here is the order in which things are rendered in a browser.
Each step uses the result of the previous operation. For example, if your code does something that triggers Layout, the Paint and Composite steps need to run again. A non-composited animation is any animation that triggers one of the earlier steps in the rendering pipeline (Style, Layout, or Paint). Non-composited animations perform worse because they force the browser to do more work.
Trying to Improve Your Core Web Vitals?
This article is part of a larger series, called Vitality, where we tackle notable metrics and Core Web Vitals!
Quick summary of CLS
- Get a CLS score of 0.1 or less to pass Core Web Vitals. Remember, this is an official metric.
- Use tools like DebugBear or WebPageTest to more easily track down where the CLS is coming from.
- Utilize Google Search Console to see if you have a bunch of URLs flagging for CLS.
- For many CLS-related things, an optimization plugin isn’t meant to fix it. Many times it comes down to the code itself. This means sometimes you might need to reach out to the theme, page builder, or plugin and ask for help.
- Make sure to add image width and height on your images. This is very important.
- Unlike what you might think, lazy loading isn’t actually a big source of CLS.
- Preload your fonts to prevent any CLS or use system fonts.
- Use placeholders when running Google Ads.
- Avoid non-composited animations.
It’s also important to remember that not everything has to be perfect. You don’t necessarily need to get CLS to 0 everywhere. However, you might want to aim for that as your goal. It is usually achievable. And don’t be afraid to reach out to the developer of whatever is causing the CLS for help.
Also, real-user data can take a while (up to 28 days) to come in. So sometimes your CLS fixes might not show up right away in terms of passing or failing. You can monitor this in PageSpeed Insights using the “origin” tab or in Google Search Console.