Excellent software and practical tutorials
What is CLS?
CLS Measure everything that happens during the page lifecycleAccidentThe largest sequence of layout offsetsLayout Shift Score.
Occurs whenever the position of a visible element changes from one rendered frame to the next.Layout offset .
A series of layout shifts, also calledSession Window, refers to one or more single layout shifts that occur in rapid succession, with each shift separated by less than 1 second and a maximum duration of 5 seconds for the entire window.
The largest chain refers to the session window with the largest cumulative score of all layout shifts within the window.
Previously, CLS measured the events that occurred during the entire page lifecycle.All single layout shift scoresTo see which tools still provide measurement capabilities in their original form, seeEvolving Cumulative Layout Offset in the Web Toolset .
What is considered a good CLS score?
In order to provide a good user experience, websites should strive to keep the CLS score within0.1 or less. To ensure that you are hitting the recommended target for the majority of your users’ visits, a good measurement threshold is75th percentile, and this threshold applies to both mobile and desktop devices.
For more information on the research and methodology behind these recommended values, see:Define metric thresholds for core web metrics
Layout Shift Details
Layout offsets are determined byLayout Instability APIDefined, as long as the element's starting position is visible in the visual area (for example, the element is in the defaultWriting ModeThe API reports that if the top and left positions of the layout-shift entries. Such elements are consideredUnstable Elements.
Note that only changes to the starting position of an existing element count as a layout shift. If a new element is added to the DOM or an existing element changes size, it does not count as a layout shift, provided that the change does not cause the starting position of other visible elements to change.
Layout Shift Score
The browser is calculatingLayout Shift Score, it looks at the size of the visible area and the visible area between two rendered frames.Unstable ElementsThe layout shift score is the product of two measures of this shift:Impact scoreandDistance score(Both are defined below).
Layout shift score = impact score * distance score
Impact score
Impact scoreMeasurementUnstable ElementsThe effect on the visible area between frames.
Previous frameandAll the current frameUnstable ElementsThe visible area set (the part of the total visible area) is the current frameImpact score.
In the above figure, an element occupies half of the visible area in one frame. Then, in the next frame, the element moves down by 25% of the height of the visible area. The red dotted rectangle represents the visible area set of the element in the two frames. In this example, the set occupies 75% of the total visible area, so itsImpact scoreis 0.75.
Distance score
The other part of the layout shift score calculation measures how far the unstable element has shifted relative to the viewport.Distance scoreRefers to anyUnstable ElementsThe maximum distance moved (horizontally or vertically) in one frame divided by the largest dimension of the viewport (width or height, whichever is larger).
In the example above, the largest viewport dimension is height, and the unstable element is displaced by 25% of the viewport height, soDistance scoreis 0.25.
So, in this example,Impact scoreis 0.75,Distance scoreis 0.25, soLayout Shift Scoreis 0.75 * 0.25 = 0.1875.
Initially, the layout shift score is based only onImpact scorePerform calculations.Distance scoreThis is to avoid over-penalizing large elements for small displacements.
The next example illustrates the effect that adding content to an existing element has on the layout shift score:
The "Click Me!" button is attached to the bottom of the grey box with black text, pushing the green box with white text down (and partially outside the visible area).
In this example, the size of the gray box changes, but the starting position does not change, so the gray box is not aUnstable Elements.
The "Click me!" button was not initially in the DOM, so its starting position did not change.
However, the starting position of the green box does change, but since part of the green box is already outside the visible area,Impact scoreThe invisible area is not considered. The set of visible areas of the green boxes in the two frames (indicated by the red dashed rectangle) is the same as the area of the green box in the first frame, which is 50% of the visible area.Impact scoreis 0.5.
Distance scoreIndicated by the purple arrow. The distance the green box moves downward is approximately 14% of the visible area, soDistance scoreis 0.14.
The layout shift fraction is 0.5 x 0.14 = 0.07.
The last example illustrates multipleUnstable ElementsSituation:
In the first frame above, there are four results from an API request for animal names, sorted alphabetically. In the second frame, more results are added to the sorted list.
The starting position of the first item in the list ("Cat") did not change between the two frames, so it is stable. Likewise, the new items added to the list were not previously in the DOM, so the starting positions of these items did not change. However, the starting positions of the items "Dog", "Horse", and "Zebra" all changed, so they are all stable.Unstable Elements.
Similarly, the red dotted rectangle represents these threeUnstable ElementsThe area of the previous and next frames, in this example, occupies about 38% of the visible area (Impact scoreis 0.38).
Arrow indicatesUnstable ElementsThe displacement distance relative to the starting position. The "Zebra" element represented by the blue arrow has the largest displacement distance, which is about 30% of the height of the visible area.Distance scoreis 0.3.
The layout shift score is 0.38 x 0.3 = 0.1172.
Expected vs. Unexpected Layout Shift
Layout shift is not always a bad thing. In fact, many dynamic web applications frequently change the starting position of page elements.
User-initiated layout shifts
Layout shifts are only bad if the user isn't expecting them to happen. In other words, layout shifts that occur in response to user interaction (clicking a link, tapping a button, typing in a search box, etc.) are generally fine, provided that the shift happens close enough to the interaction that the user can tell the context clearly.
For example, if a user interaction triggers a network request that may take a while to complete, it’s better to immediately make some space and display a loading indicator to avoid annoying layout shifts while the request completes. If users don’t realize something is loading or don’t know when the resource will be ready, they may try to click on other content while they wait.
Layout shifts that occur within 500 milliseconds of user input are marked withhadRecentInputFlag to exclude these offsets from calculations.
Note: The hadRecentInput flag applies only to discrete input events, such as touches, clicks, or key presses. Continuous interactions such as scrolling, dragging, or pinch-to-zoom gestures do not count as "recent input." For more information, seeLayout Instability Specification.
Animations and transitions
Animations and transitions, when done well, are a great way to update page content without surprising the user. Sudden and unexpected shifts in page content almost always result in a bad user experience. But if content moves gradually and naturally from one position to the next, it often helps users better understand the current situation and guides them through the changes between states.
CSS transformProperty enables you to animate an element without triggering a layout shift:
- Use transform: scale() instead and adjust the height and width properties.
- If you need to move the element around, you can use transform: translate() instead and adjust the top, right, bottom, or left properties.
How to measure CLS
CLS can belaboratoryMeasure oractualMeasured and can be used in the following tools:
Note: Labs tools typically load pages in a synthetic environment and can therefore only measure layout shifts that occur during page load. Therefore, the CLS value that Labs tools report for a particular page may be lower than what real users actually experience.
Measurement tools
- Chrome User Experience Report
- PageSpeed Insights Web Page Speed Measurement Tool
- Search Console (Core Web Metrics Report)
- web-vitals JavaScript library
Laboratory Tools
Measuring CLS in JavaScript
To measure CLS in JavaScript, you can useLayout Instability APIThe following example shows how to create aPerformanceObserverto listen for unexpected layout-shift entries, group the entries by session, record the maximum session value, and update the record when the maximum session value changes.
let clsValue = 0;
let clsEntries = [];
let sessionValue = 0;
let sessionEntries = [];
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
// Only take into account layout offsets without the most recent user input flag.
if (!entry.hadRecentInput) {
const firstSessionEntry = sessionEntries[0];
const lastSessionEntry = sessionEntries[sessionEntries.length - 1];
// If the time between the entry and the previous entry is less than 1 second and
// If the time between the first entry and the session entry is less than 5 seconds, then the entry
// Include 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 greater than the current CLS value,
// Then update CLS and its related entries.
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});
Warning: The above code illustrates the basic method of calculating and recording CLS. However, to accurately measure CLS and toChrome User Experience Report If the measurement matches the value in (CrUX), then the measurement is more complicated. See below for details:
In most cases, the current CLS value when a page is unloaded is the final CLS value for that page, but there are some important exceptions:
The following sections list the differences between what the API reports and how the metrics are calculated.
Differences between indicators and APIs
- If the page is loaded in the background, or the page is moved to the background before the browser paints anything, then the page should not report any CLS values.
- If the page passesRoundtrip CacheIf the page is restored, the CLS value for that page should be reset to zero, because this is a different page visit experience for the user.
- The API does not report layout-shift entries based on offsets within the iframe, but to measure CLS correctly you should account for these offsets. Child frames can use the API to report these offset layout-shift entries to the parent frame forpolymerization.
Since CLS measures the entire page lifecycle, in addition to the above exceptions, this metric has some additional complexities:
- Users mayveryLeaving a tab open for a long period of time (days, weeks, months). In fact, the user may never close the tab.
- On mobile OSes, browsers generally don't run page unload callbacks for background tabs because that would make it difficult to report a "final" value.
To handle these situations, you should report CLS whenever the page is in the background, even when the page is unloaded (visibilitychange eventThe analysis system that receives the data needs to calculate the final CLS value at the back end.
Instead of having to remember all of these cases and deal with them on their own, developers can useweb-vitals JavaScript libraryTo measure CLS, the library handles all the above cases by itself:
import {getCLS} from 'web-vitals';
// In all cases where CLS needs to be reported
// Measure and record it.
getCLS(console.log);
You can refer to the source code of (getCLS) for a complete example of how to measure CLS in JavaScript.
In some cases (such as cross-domain iframes), CLS cannot be measured in JavaScript. See the web-vitals library for more details.limitationpart.
How to improve CLS
For most sites, you can avoid all unexpected layout shifts by following a few guidelines:
- Always include size attributes on your image and video elements, either by usingCSS Aspect Ratio Container. This approach ensures that the browser allocates the correct amount of space in the document while the image is loading. Note that you can also useunsized-media feature policyThis behavior is enforced in browsers that support feature policies.
- Never insert content above existing content unless it is in response to user interaction. This ensures that any layout shifts that occur are expected.
- Prefer transition animations over property animations that trigger layout shifts. The goal of animated transitions is to provide contextual continuity between states.
For more information on how to improve CLS, seeOptimizing CLSandDebugging layout shifts.