Boost Your Website Performance: Fixing Cumulative Layout Shift (CLS) On Your Website

October 26, 2024 (2mo ago)

Ah, CLS - it's one of those acronyms that you probably heard if you've been around web development long enough. Google has made CLS, or Cumulative Layout Shift, a big deal for website performance and user experience, especially with the introduction of Core Web Vitals. But let's be honest: it's not just a Google thing; users notice it too. You've probably experienced it yourself - you're reading an article, maybe you're about to click a link, and bam! The whole page jumps, and suddenly you're clicking on an ad you didn't mean to touch. It's annoying, right? But more than annoying, it can cause users to abandon a site, and for developers and website owners, that's a big problem.

In this post, we're going to dive into CLS, why it happens, and how we can tame it with some strategic tweaks. And since we're all about making it stick, we'll walk through interactive examples you can try out right here to see how each fix actually works. Sound good? Let's get into it.

What Is CLS, Anyway?

CLS stands for Cumulative Layout Shift, and it's a metric that captures those sudden shifts in content layout while a page is loading. This might sound small, but every time a layout shift happens, it interrupts the user experience and creates friction for the reader. And a high CLS score can seriously impact your search rankings, thanks to Google's focus on Core Web Vitals.

In simple terms, CLS measures how much visible content shifts around on the screen as the page loads. The more things shift, the higher the score. A CLS score of 0 is ideal - that means there are no shifts at all. But realistically, most websites have some shifting, so a score under 0.1 is considered good.

Now, what causes CLS? It often happens because of things loading in “late” - images, ads, embeds, fonts, you name it. They all have one thing in common: they're loading after the initial HTML content has already rendered. If we don't give the browser any clues about where these elements will appear, it just loads the page as best it can, and the elements “push” things around once they're in. It's like trying to decorate a room with no sense of where the furniture should go.

Common Causes Behind Poor CLS

Before we jump to solutions, let's pinpoint the common causes of layout shifts. Here's what usually triggers them:

  • Images and videos without dimensions: If the browser doesn't know how much space to reserve for an image, it can't plan the layout, so things move around once the image loads.

  • Ads, embeds, and iframes: These are notorious for causing unexpected shifts because they're often injected after the main content has loaded.

  • Custom fonts: If a font loads after the page displays, the text can shift around to accommodate the new style.

  • Dynamic content: Things like notifications or pop-ups that load after the initial page load can push content around too.

But don't worry - each of these has a fix. Let's take a look.


Fixing CLS: Step-by-Step Solutions

I'm not just going to throw a list of recommendations at you. We're going to look at each common issue and see how a small adjustment can prevent these layout shifts.

Specifying Image Dimensions

One of the biggest causes of CLS is images without width and height attributes. When the browser knows the exact dimensions, it can allocate space, and no sudden shifts will occur once the image loads. But instead of just telling you, I want you to try this out!

A bunny in human hands

Watch how it loads with and without that space allocated in advance.

This is why you should always specify width and height attributes in img tag.

Here's how we can fix this :

<img src='image.jpeg' alt='this is an image' title='image' width='250px' height='250px'>

Let's try and implement this again and see the difference.

A bunny in human hands

Now, you can see the difference in the layout shift when the image loads. The space is already allocated for the image, so there is no shift in the layout.

You can also check the Network tab in the Inspect Element tool to see the whether the images are being loaded or not 😅

Interactive Example: CSS Aspect Ratios for Responsive Media

Another way to handle layout shifts for media like videos is by setting an aspect ratio in CSS. This allows you to maintain the right space for your media across different screen sizes without worrying about shifts.

Try out the example below: you can change the aspect ratio on the fly and see how the video space adapts seamlessly.

Interactive Example: Using font-display for Custom Fonts

Have you ever noticed that text on some websites loads in one font and then “jumps” to another? This happens because the custom font takes a little while to load, and the fallback font is displayed in the meantime. By using the font-display property, we can control how the font loads and prevent this shifting.

In this example, you'll see what happens when we apply font-display: swap; to a custom font. Check out the difference!

Interactive Example: Preventing Shifts with Skeleton Screens

When we know something will load but don't know exactly how fast, skeleton screens can be a lifesaver. These are placeholder shapes that match the final content's layout, so users have a smooth, predictable experience while waiting.

Here's an example where we use skeleton screens for loading content. Toggle it on and off to see how it keeps things steady.


Final Thoughts

Cumulative Layout Shift can feel a bit intimidating at first, but once you know what's causing it, there are straightforward solutions to get it under control. I hope these examples helped you see the changes in action – sometimes, a small tweak here and there can lead to big improvements in user experience. Your site visitors might not know what CLS is, but they'll definitely notice when your page loads smoothly without those distracting jumps. And hey, Google will notice too, so it's a win-win.

Got any CLS issues that aren't covered here? Let me know in the comments, and let's figure it out together!