Cumulative Layout Shift
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?
|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
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?
|Optimize CSS Delivery 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 > Optimize CSS Delivery.
Documentation: Optimize CSS Delivery.
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 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/Combine CSS
|| This allows WP Rocket to add the
Path on WP Rocket: WP Rocket > File Optimization.
Documentation: CSS minify and combine.
What features make CLS worse?
|CPCSS if it generates a FOUC|| The unstyled content will cause layout shift.
Find and exclude CSS from CPCSS when it’s possible.
Documentation: Exclude files from Optimize CSS Delivery.
|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.
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.
Documentation: Exclude files from Defer JS.
Causes of CLS that WP Rocket cannot fix
|Animations|| WP Rocket can't control or enhance animations.
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;
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.
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.
Add the height/width to iframes and elements with dynamic content manually.
- https://layoutstability.rocks/ - Quickly calculate CLS score.
- https://gtmetrix.com/ - The last update has PageSpeed integrations and focusing more on web vitals, including CLS.
- https://web.dev/cls/ - Google’s documentation.