How to calculate CLS
Cumulative Layout Shift (CLS, Cumulative Layout Shift) is an important user-centric metric to measure visual stability because it helps quantify how often users experience unexpected layout shifts. The effect of lower CLS is that the interaction flow is natural, without delay and stuttering.
Description of indicators
CLS measures the largest series of layout shift scores that occur over the life of a Unexpected Layout Shifts page. A layout offset occurs whenever the position of a visible element changes from one rendered frame to the next. For more information, see layout shift score.
How is the CLS score calculated?
When the browser calculates the layout offset score, it looks at the size of the viewable area and the displacement of unstable elements in the viewable area between two rendered frames. The CLS score is the product of two measures of this displacement: the influence score and the distance score (both defined below).
CLS score = impact score * distance score
Affect the score
Impact Fraction Measures the effect of unstable elements on the visible area between two frames. The set of visible areas (part of the total visible area) of all unstable elements of the previous and current frames is the influence score of the current frame.
In the image above, there is an element that takes up half of the visible area in a frame. Then, in the next frame, the element is moved down by 25% of the height of the viewable area. The red dashed rectangular box represents the set of visible areas of the element in both frames, which in this example accounts for 75% of the total visible area, so its influence score is 0.75
.
Distance score
Another part of the CLS score calculation formula measures the distance that the unstable element is displaced relative to the visible area. The distance refers score to the maximum distance (horizontal or vertical) that any unstable element is displaced in a frame divided by the maximum size dimension (width or height, whichever is greater) of the viewable area.
In the example above, the largest viewable area size dimension is height, and the displacement distance of the unstable element is 25% of the viewable area height, so the distance score is 0.25. So, in this example, the impact score is 0.75
, the distance score is 0.25
, so the CLS score is 0.75 * 0.25 = 0.1875
.
Initially, CLS scores were calculated based on impact scores only. The distance fraction is introduced to avoid the situation of excessive penalization in the case of small displacements of large elements.
Expected Layout Offset vs. Unexpected layout offset
Layout offset is not always a bad thing. In fact, many dynamic web applications often change the starting position of page elements.
Layout offset initiated by the user
A layout offset is only a bad thing if the user doesn't expect it to happen. In other words, layout offsets that respond to user interaction (clicking a link, tapping a button, typing information into a search box, etc.) are generally fine, provided that the timing of the offset occurs close enough to the interaction timing that the context is clear to the user.
For example, if a user interaction triggers a network request that may take some time to complete, it may be a good idea to immediately set aside some space and display a loading indicator to avoid an undesirable layout shift for the user when the request completes. If the user is not aware that something is currently loading, or does not know when the resource will be ready, they may try to click something else while waiting. Layout offsets that occur within 500 milliseconds of user input are [hadRecentInput](https: //wicg.github.io/layout-instability/#dom-layoutshift-hadrecentinput) flagged so that they can be excluded from the calculation.
Notice:
hadRecentInput
Flags apply only to discrete input events such as a tap, click, or key operation. Sequential interactions such as scrolling, dragging, or pinch-to-zoom gestures do not count as "recent input .". For details, see Layout Instability Specification.
What is a good CLS score?
In order to provide a good user experience, websites should keep their CLS scores at or below 0.1. To ensure that you can achieve the recommended target values during most user visits, a good measurement threshold is the 75th percentile of page loads, and this threshold applies to both mobile and desktop devices.
Metrics capture implementation details
Layout Shift is defined by Layout Instability API, and the API reports a layout offset when an element visible in the view changes its starting position between frames. These elements are considered to be unstable.
Create a PerformanceObserver to use Layout Instability API to listen for unexpected layout changes.
let clsValue = 0;
let clsEntries = [];
let sessionValue = 0;
let sessionEntries = [];
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
// Only count layout shifts without recent user input.
if (!entry.hadRecentInput) {
const firstSessionEntry = sessionEntries[0];
const lastSessionEntry = sessionEntries[sessionEntries.length - 1];
// If the entry occurred less than 1 second after the previous entry and
// less than 5 seconds after the first entry in the session, include the
// entry in the current session. Otherwise, start a new session.
if (sessionValue
&& entry.startTime - lastSessionEntry.startTime < 1000
&& entry.startTime - firstSessionEntry.startTime < 5000) {
sessionValue += entry.value;
sessionEntries.push(entry);
} else {
sessionValue = entry.value;
sessionEntries = [entry];
}
// If the current session value is larger than the current CLS value
// update CLS and the entries contributing to it.
if (sessionValue > clsValue) {
clsValue = sessionValue;
clsEntries = sessionEntries;
// Log the updated value (and its entries) to the console.
console.log('CLS:', clsValue, clsEntries)
}
}
}}).observe({type: 'layout-shift', buffered: true});javascript
Browser compatibility instructions
The indicator requires the browser to support Largest Contentful Paint, Layout Instability API and PerformanceObserver. In the case of incompatibility, isSupport is false in the reported indicator.
How to optimize CLS
- Include size attributes in the picture and video elements, or reserve the space you need with something like a CSS aspect ratio box.
- Do not insert content on top of existing content, except in response to user interaction.
- Use transform animations instead of animations properties that trigger layout changes.