Skip to main content

Cumulative Layout Shift

Cumulative Layout Shift (CLS) measures how much content moves around on the page after being rendered. The lower the CLS is the better. A value of 0 means the layout is completely stable.

Layout shifts hurt user experience, as they can cause accidental clicks on the wrong element or make users lose track of where they were when reading an article.

CLS is one of the Core Web Vitals, a set of three key web performance metrics defined by Google. From 2021 it will contribute to the page experience signal that Google uses for search rankings.

Example of layout shift​

This filmstrip shows an example of page content shifting around after first being rendered. When the banner loads, the heading and article below it shift downward to make space for the banner.

For this page the CLS value is 0.13.

Comulative Layout Shift filmstrip showing different rendering stages

If you look closely there are actually two layout shifts on this page. The first one occurs after 2.5s when the webfont loads, causing the title and description to re-render. After this, the description takes up a little less space, and the content below it shifts upward.

Cumulative Layout Shift in Lighthouse​

You can find the CLS metric as one of the 6 key metrics at the top of each Lighthouse report.

The filmstrip below can help identify what's causing the layout shift.

Performance metrics at the top of the Lighthouse report

There's also a more detailed "Avoid large layout shifts" audit, which breaks down different LayoutShift events as reported by Chrome.

CLS audit in the Lighthouse Performance section

How does Cumulative Layout Shift affect Lighthouse scores?​

The Cumulative Layout Shift score currently accounts for 5% over the overall Lighthouse Performance score.

The CLS metric should be as low as possible, ideally below 0.1. A CLS above 0.25 is considered poor.

Breakdown of the Lighthouse Performance score

How do reduce Cumulative Layout Shift​

Layout shifts during the initial page load usually happen when the initial page HTML has been returned by the server, but additional resources like JavaScript and images are still loading. When these resources do load the layout shift occurs.

A common example would be ads, which are often loaded from a different server owned by the ad network, and therefore might take an extra second or two to load.

You can prevent layout shifts if you know the size of the element that's being loaded. In that case, you can provide an empty placeholder with the appropriate height, and then fill in the contents later.

Web fonts​

Web fonts can also cause layout shifts, as the size of rendered text changes once the fonts have loaded.

You can reduce these layout shifts by using setting the font-display CSS property to either optional or fallback. Both will hide the text for up to 100ms, completely preventing layout shifts if the web font loads quickly. If the font loads slowly the browser will use a system font initally.

font-display: fallback switches to the web font if it loads within 3s. font-display: optional never shows the web font if it takes more than 100ms to load.

Simon Hearne has written an article all about preventing layout shifts caused by web fonts.

Web fonts causing layout shifts

Why is Cumulative Layout Shift different in field and lab data?​

Lab data is in an isolated test environment while field data is collected from real users. Lighthouse lab data only tests layout shifts during the initial page load, while field data also counts layout shifts that users experience when scrolling down the page. This can lead to discrepancies and sometimes make Cumulative Layout Shift difficult to debug.

Layout Instability API​

You can use the Layout Instability to detect layout shifts inside your application, and calculate the Cumulative Layout Shift on the fly.

Here's how to use a PerformanceObserver to retrieve and monitor layout-shift entries:

var cumulativeLayoutShift = 0;

const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
// Don't count if the layout shift is a result of user interaction
if (!entry.hadRecentInput) {
cumulativeLayoutShift += entry.value;
console.log({ entry, cumulativeLayoutShift });

// `buffered: true` to report layout shifts that have already happened on the page
observer.observe({ type: "layout-shift", buffered: true });

A layout-shift entry looks like this – each event is attributed to a set of DOM nodes.

Entry in the Layout Instability API

Layout Shifts in Chrome DevTools​

Chrome DevTools can highlight layout shifts as part of its Animation tooling. First, click the three dots in the top right corner, then select More tools, and finally click Animations.

DevTools More tools menu item

You can then enable highlighting for Layout Shift Regions.

DevTools animations pane

Now, when content moves on the page, Chrome will show a blue highlight rectangle for the affected DOM nodes.

Layout Shifts highlighted on the inspected page

Cumulative Layout Shift in DebugBear​

You can find the Cumulative Layout Shift metric in the page Overview tab, just below the filmstrip.

Cumulative Layout Shift in DebugBear

The Performance tab also contains a list of all layout shifts on the page and provides in-depth diagnostics to help you improve your Cumulative Layout Shift score.

Cumulative Layout Shift in DebugBear

Changes to how Cumulative Layout Shift is defined​

Different versions of Chrome measure CLS slightly differently. Google keeps track of changes to the CLS definition here.

DebugBear is a site speed monitoring service. Start tracking Lighthouse scores and Core Web Vitals in minutes.
Start Monitoring Your WebsiteGo To App