Cumulative Layout Shift (CLS)

Visual Stability

Largest Contentful Paint (LCP)

Cumulative Layout Shift (CLS)

TIPS: Do not move HTML elements after finishing rendering the elements..

Cumulative Layout Shift (CLS)

If you move your elements after finishing rendering. It looks like cheating to the users. Let the users don’t know how to interact with your websites.

For instance like below:

The users want to Cancel the orders and click No, go back button. Suddenly, the layouts change and let the users click the wrong button to Confirm the order.

This will let the users have bad experiences on your websites. And the Google will punish this kind of websites. Let the SEO ranking become worse.

We call this Cumulative Layout Shift (CLS).

Layout shift score

The score is cumulative, the higher score means bad

Cumulative Layout Shift (CLS)

Algorithm of layout shift score = A. Impact fraction * B. Distance fraction

A. Impact fraction

The element’s original visible area is 50%. After the element was moved, it is affect 75% of the total viewport.

So the Impact fraction is 0.75.

Cumulative Layout Shift (CLS)

B. Distance fraction

The moving distance is about 25% of the total viewport.

So the Distance fraction is 0.25.

Cumulative Layout Shift (CLS)

The layout shift score of this element will be 0.75 * 0.25 = 0.1875.

And if you have a lot of elements moving after rendering. Then it will cumulative all layout shift score for all elements.

The final score is your Cumulative Layout Shift

Most common causes of a poor CLS

Cumulative Layout Shift (CLS)

  • Images without dimensions
  • Ads, Embeds, iFrames without dimensions
  • Dynamically injected Content
  • Web Fonts Causing FOIT(Flash of Invisible Text) / FOUT (Flash of Unstyled Text)

FOIT(Flash of Invisible Text)

Loading the fonts was too slow. The fonts can not show up. But when fonts load finish and the pages will flash

FOUT (Flash of Unstyled Text)

Loading the fonts was too slow. And the browser use the default fonts instead. But when fonts load finish and the pages will flash

Optimizing Cumulative Layout Shift (CLS)

1. Different text rendering strategy with the CSS descriptor

Set font-display to optional.

  1. If the primary font does not load in the first 100ms, the text is rendered using the fallback font.
  2. Next time you visit the page the web font will be used if loaded successfully.

This strategy allows us to minimize repaints and CLS.

preload resource

We can combine font-display optional with <link rel="preload"> to preload optional fonts and completely eliminate layout shifting.

2. Optimizing Animations

Composite animations using properties like transform and opacity do not cause such recalculations

transform: 'translate3d(' + -slide_number * 100 + 'vw, 0, 0)';

3. Enforce Scrollbar Appearance

This should force the scrollbar to show all the time, preventing horizontal layout shift

html { overflow-y: scroll }

4. Content dynamically injected with JavaScript

Left the placeholder for inserting the same size element after rendered.

e.g. advertisement elements

Cumulative Layout Shift (CLS)

Possible solutions:

  1. Avoid using JavaScript to style or generate content wherever possible.
  2. Overlay small dynamic content, e.g. with absolute positioning properties, to cover the existing elements instead of shifting them.
  3. For larger elements, reserve space on the page in advance - for example, show them out of the main content flow (in the sidebar) or use the skeleton/placeholder strategy.
  4. If possible, add dimensions to iframes and other elements with dynamic content.
  5. Optimize loading strategy for late-discovered scripts that populate components with content. Defer the scripts used to add elements above the fold that will likely cause layout shift.

5. Add Size Attributes to Images and Video

Always include width and height size attributes on your images and video elements to ensure sufficient space is allocated on the page before the browser started fetching them.

<img src="example.jpg" width="360" height="180" alt="example">

Default aspect ratio on browser will be

<style>
  img {
    aspect-ratio: attr(width) / attr(height)
  }
</style>

6. Add container with fixed dimensions for dynamic content

<style media="screen">
  .container {
    display: block;
    width: 720px;
    height: 90px;
    background: #ccc;
    overflow: hidden;
  }
</style>

<div class="container">
  <iframe src="...">
</div>

Cumulative Layout Shift (CLS)

Reference