Cumulative Layout Shift
Wondering what Cumulative Layout Shift means and what's the impact on your UX and SEO performance? Check our Core Web Vitals Hub!
You’ll find out what CLS is, how you can test it, and what factors affect its score. You’ll discover how to improve a bad grade (Cumulative Layout Shift more than 0.1) and improve your WordPress performance. Everything in plain English!
What is Cumulative Layout Shift?
CLS measures the amount of unexpected layout shift that occurs during page load, and during the time that the visitor is on the page. Large layout shifts provide a poor user experience since the user may click on the wrong element, or their reading may be disrupted if the text moves unexpectedly.
Source - https://web.dev/cls/
You will find it as part of Google PageSpeed (or Lighthouse) reports.
A layout shift is how an element changes position while the page is loading.
Here is an example of layout shift:
The CLS metric focuses on unexpected layout shifts on testing tools. Meaning, it only counts the layout shifts not induced by user interaction (mouse hover, click on a button).
Layout shifts depend on how elements change their size and position. The bigger the element, the more noticeable the change will be, and the more intense its influence will be on other neighboring elements.
Important: CLS is calculated during the whole page lifecycle from loading until exit. So, all layout shifts happening in-between will be part of the final CLS score for a particular visit.
What causes layout shift?
Cause | Example | Impact |
Images without dimensions | Images without explicitly setting height and width | High |
Dynamically injected content | Ads, embeds, and iframes without dimensions | High |
Web Fonts causing a Flash of Unstyled Text (FOUT) | Fonts declared after styling an element | Low generally - High for large text |
Actions waiting for a network response before updating DOM | Elements depending on APIs calls, like Instagram Galleries | High on mobile network |
Animations | Use CSS transition animations instead of animating properties | Low |
CLS has a greater impact on mobile
Smaller viewport
Not all elements scale to fit the screen size perfectly. What usually happens is that the same element will take more vertical space on mobile. So, any layout shift will have a significant "distance" change.
It is common to see mobile CLS worse than its desktop counterpart.
Mobile network increases assets loading time
The slower a CSS, JS, or AJAX call is loaded, the more impact it has on mobile CLS.
Mobile has weaker CPUs
This will usually have an impact if the CLS is worsened by elements requiring complex JS processing.
How to find out what’s causing CLS on your page
The Avoid Large Layout shift audit found under Diagnostics will tell you which specific elements are causing the layout shift on your page:
How does WP Rocket improve CLS?
Feature | Why |
Load CSS Asynchronously if it doesn't generate a Flash of Unstyled Content (FOUC) | CPCSS will help speed up the display of above the fold content, without having any render-blocking element. Path on WP Rocket: WP Rocket > File Optimization > Load CSS Asynchronously. Documentation: Load CSS Asynchronously. |
Delay JavaScript Execution targeting elements above the fold | Stops dynamic interaction, content injection (ads), dynamic class changes until there is an interaction on the page. Path on WP Rocket: WP Rocket > File Optimization > Delay JavaScript execution > Scripts to delay. Documentation: Delay JavaScript Execution. |
Lazyload YouTube videos with preview image |
The preview image helps stabilize the layout. Path on WP Rocket: WP Rocket > Media > LazyLoad > Enable for iframes and videos > Replace Youtube iframe with preview image. Documentation: Choose YouTube Preview Image Resolution. |
Preload fonts | Gives more chances to avoid "Flash of Invisible Text" ( FOITs). Path on WP Rocket: WP Rocket > Preload > Preload fonts. Documentation: Preload Fonts. WP Rocket also groups Google fonts and add the swap attribute automatically, which activates preloading their fonts. |
Add missing image dimensions | It will set a static dimension for images. No layout shift will happen even if the images are lazy-loaded. Path on WP Rocket: WP Rocket > Media > Add missing image dimensions. Documentation: Add Missing Image Dimensions. |
Minify CSS files |
This allows WP Rocket to add the font-display: swap; missing on font-display properties. Path on WP Rocket: WP Rocket > File Optimization. Documentation: Minify CSS files. |
What features make CLS worse?
Feature | Why |
Load CSS Asynchronously if it generates a FOUC | The unstyled content will cause layout shift. Fix Find and exclude CSS from Load CSS Asynchronously when it’s possible. Documentation: Exclude files from Load CSS Asynchronously. |
Lazyloading images above the fold | If the image doesn’t have dimensions set, it will cause the layout shift if used with lazy loading. Like when the menu expands, for example, before/after the logo image shows up. Fixes Exclude images above the fold from lazy load. Path on WP Rocket: WP Rocket > Media > LazyLoad > Excluded images or iframes. Documentation: Disabling LazyLoad on Specific Images Add height/width for images feature will also help. Path on WP Rocket: WP Rocket > Media > Image Dimensions. Documentation: Add Missing Image Dimensions. |
Load JavaScript Deferred | When JavaScript is needed to display elements above the fold, deferring it will create layout shift.Example: Slider late loading will significantly push the content and be flagged as a significant layout shift. Fix Exclude the JavaScript files needed to display above-the-fold content. Path on WP Rocket: WP Rocket > File Optimization > Load JavaScript deferred > Exclude JavaScript Files. Documentation: Exclude files from Defer JS. |
Causes of CLS that WP Rocket cannot fix
CLS cause | Why |
Animations | WP Rocket can't control or enhance animations. Fix Some design and coding decisions need to be made. Like using transform animations instead of properties animations. For example, let’s say we have an element with the following properties: height: 100px; width: 100px; Using width: 200px; height: 200px; Will induce a change of position while changing the size, triggering a layout shift. |
Content injections on the viewport, especially when it's inserted above elements | Injecting dynamically content before elements will result in pushing whatever is at the bottom. Not only the faulty element will be flagged for layout shift (change of aspect ratio and position), but everything else below it as well (change of vertical position).Example: AJAX notification boxes dynamically added such as WooCommerce order status. Fix Re-think the use of the element inducing the CLS. |
Missing iframe or injected content width and heights | The iframe, or the injected element will expand when loaded, causing a layout shift. Fix Add the height/width to iframes and elements with dynamic content manually. |
Tools
- https://layoutstability.rocks/ - Quickly calculate CLS score.
- https://gtmetrix.com/ - The last update has PageSpeed integrations and focusing more on web vitals, including CLS.
Resources
- WP Rocket Core Web Vitals Hub - Cumulative Layout Shift
- https://web.dev/cls/ - Google’s documentation.