Check out a free preview of the full Web Performance Fundamentals, v2 course
The "Layout Size Hints" Lesson is part of the full, Web Performance Fundamentals, v2 course featured in this preview video. Here's what you'd learn in this lesson:
Todd discusses how CLS can affect the smoothness and predictability of elements loading on a webpage. He also demonstrates how to improve CLS by giving layout size hints and specifying the height and width of images, as well as providing examples of different approaches to solving CLS issues caused by late-rendered content.
Transcript from the "Layout Size Hints" Lesson
[00:00:00]
>> Todd Gardner: Okay, let's talk about improving CLS, the cumulative layout shift. If you don't recall, CLS is how smooth and predictably elements load onto the page. And arguably, we might have made our CLS a little worse with what we did. Because we instructed the browser to lazy load a whole bunch images, which means some images are gonna come in later than we thought and push things around.
[00:00:29]
So let's take a look at where we're at right now with CLS. If we go to our foreign version, we have a bunch of CLS happening. Our dev tools for this, if we pop up in the dev tools console says, hey, we have a poor CLS. In fact, we had two different CLSs happen, cuz it got a lot worse.
[00:00:52]
There's a couple of different things happening here. There was a CLS of 2.56, the hero shifted, the product shifted, all kinds of things are moving around and we don't have a really great experience right now. There's a couple of reasons for this, both the hero and the featured products moving, and there are two different issues that we need to address.
[00:01:16]
Before we dig into this and the tactics, like all of the metrics, all the improvements, you need to decide whether or not this is a problem for you. Don't go fixing or worrying about things that don't directly affect your data. There's really only one tactic here. There's really one thing you do for CLS as you give your layout size hints.
[00:01:37]
You tell it, here's how big things are going to be ahead of when they actually appear. Now, there's only one, because that's the only thing this is measuring. CLS in a lot of cases, is a problem created by LCP performance tactics. Is we try to delay a bunch of stuff to get LCP fast, and it creates layout shift problems down stream, and we fix those problems by giving appropriate layout hints.
[00:02:04]
Here's an example. So here is a film strip of some of our lazy-load Images. Let's zoom in on the particular problem. As this page is loading, when we first decide that there's a reference to an, image up on the top, there's the logo for developer stickers. It's not there, it's lazy-loaded.
[00:02:23]
It's one of the resources we told to load later. And so at some point during the lifetime of the page, it's done. And when it is, the whole header shifts to the right, creating a layout shift because the image popped in. We also have a layout shift down there in featured product, where the image of each product is lazy-loaded.
[00:02:44]
But it's not there initially, and whenever it's loaded, it pushes everything down.
>> Todd Gardner: Now, we can fix these lazy-loaded image problems simply by just specifying a height and width. Something that we probably should have been doing since the beginning of time, we just haven't always done it. Now, one thing that I see a lot of developers mistake is they put the PX in there, they say 500PX, that's incorrect syntax, it's always PX.
[00:03:11]
If you put PX in there, some browsers break. Don't put the PX in there, just put the number of how big the raw image is. Not even how big you're gonna display it, just put how big the image is. And the reason we put that in this case, it's 500 pixels wide for a teeny tiny logo, is that it's not about the raw numbers, it's really about the aspect ratio.
[00:03:37]
The browser is just gonna take those numbers and figure out how big is the dimension? How big is the aspect ratio of this image? So that with wherever I have to put it, I know the size dimension. I know that it's this tall, I know how wide it is, because you gave me the aspect ratio.
[00:03:56]
So the other reason that we get layout shift is from a late-rendered content. So asynchronous content that gets client-side rendered, and we have some of that, too. So we have this promo banner that pushes down. And this promo banner, initially, doesn't even exist. At some point during the page life cycle, it decides, hey, I wanna show the user this promo., and it pushes this thing down.
[00:04:19]
And it creates this creates a big layout shift during the whole sequence. Well, how do we do this? How could we solve that? Well, it's a bit of a style thing. How do you want to do that? There's a reason why a lot of sites do that annoying thing where they push something into place because it's attention grabbing.
[00:04:36]
It's like, something interesting just happened, I wanna click on that. It's an advertisement or a promotion or whatever. So there's a couple of different ways we can do it. One, we could just set the height of the promo banner. It's always going to be 260 pixels tall. We could just specify that.
[00:04:53]
And then from as soon as the page loads, it's always there, nothing moves which definitely solves the CLS problem, but it might not be attention grabbing enough for the user. It might not sell stickers. And ultimately, that's what we're trying to do here, man. We're trying to sell some stickers, so we might still want to be attention grabbing.
[00:05:15]
And so instead of pushing all the content down, maybe we just wanna draw over the content. Maybe we just wanna expand on top of what they were looking at. So we could set some CSS to say, hey, we're gonna position this thing absolutely over the hero image. And whenever we render it in, it's just gonna slide down and be just below the header.
[00:05:37]
This is a style thing based on what elements you're doing, what you're doing it for, the purpose of it is. I'm not saying either one of these is right or wrong in your situation. These are just two really common ways you can solve this CLS. You can either fix code.
[00:05:53]
Here's how big this thing is. I'm gonna reserve this space. Or you can say, this thing that's late, this thing floats above the document. It's not going to affect anything else, because it exists at a higher plane of existence. So let's play with that and let's remove those.
[00:06:12]
So let's jump in the code, we will set image height and width.
>> Todd Gardner: So we should do this. If we were good developers, being very thorough, we would go through this entire application and set height and width on every single image, because we don't know where the user's gonna be when things load.
[00:06:32]
That would actually take a lot of time that we're not gonna use right now. So instead, we're gonna set the height and width for all the images above the fold to make sure that our visible CSS for our testing purposes are all set, and so there's only a couple of those.
[00:06:46]
First, there's this image that's lazy-loaded right here in the header, and we know that this one is height, 500 pixels high, and width, 500 pixels wide. And second, we know that the featured images, we already set it here on the main hero. And then we have this grid of featured images, which I forgot how big they are.
[00:07:15]
They are,
>> Todd Gardner: Square 1024 by 1024.
>> Todd Gardner: And I'm just gonna copy that down and put them on all four of these images here.
>> Todd Gardner: And then we also have an image that loads inside of promo.js. There's actually an image that comes down inside of this promo bar.
[00:07:58]
So that's all client side-rendered, I'm just gonna add that here as well. That's the same image, 1024 by 1024.
>> Todd Gardner: And then the other thing that we need to do is we need to set some CSS on how the promo bar is displayed. So I like the absolute case for this, cuz again, we're trying to sell some stickers and I wanna grab some attention.
[00:08:22]
So we're gonna drop that in right over the top of where things are. Now, we've already bundled all of our CSS. In a really annoying way, we'll have to re-bundle. So I'm gonna opt, I have both options kinda commented out here. So I'm gonna do the promo banner has absolutely rendered top 60, which is the height of the header, full width, and on top of everything else.
[00:08:49]
We need to run bundle npm, start. Let's just look at it locally then. Thank you, though. We cached it. [LAUGH] We've performance optimized and we cached it. So that's why this disable Cache button here exists, [LAUGH] is when you've optimized things, you probably want to see your latest changes.
[00:09:12]
[LAUGH] So let's try that again with our local cache. And now, our promo banner pushes down over the top of content. All right, so we got largely a 0 CLS. Everything is loading pretty much instantly, because our biggest problem was that promo banner that used to push down and rearrange almost the entire viewport.
[00:09:33]
And now, by shifting to where it is and by changing where those images are, we're down to pretty much 0, which is good. That's why I say there's one tactic here. You tell the layout how big things are, and this problem goes away. It goes to pretty much nothing.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops