Slashing layout cost with content-visibility - HTTP 203

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
JAKE: All right, so I think I might do the intro as part of this rather than just picking up a random intro, but we'll see. SURMA: Give me one sec. JAKE: We'll see how it goes-- see how it goes. Are you ready, Surma? SURMA: Needed a quick emergency sip. Yeah, let's go. [MUSIC PLAYING] JAKE: Hello, Surma. SURMA: Hello, Jake. JAKE: You've seen this before. SURMA: Don't I know it. JAKE: Yeah, this is the HTML spec. This is the full version of the spec. This is the 12 megabytes-- SURMA: Eight megabytes? 12? Wow. JAKE: 12 now-- they keep adding to it, it turns out. SURMA: Oh, damn. JAKE: I actually measured how high this is. This is 1.7 million pixels high at this rough size. It's a big document-- a pretty big document. SURMA: It's got a lot of APIs to cover. JAKE: Yes, it takes ages to fully load, and it is janky all of the time that it is loading. The bottleneck here is layout, as you can see from this bit of Chrome DevTools here. It takes over 50 seconds' worth of layout, and that is on a high-end MacBook Pro. So yeah, don't do that-- SURMA: Yeah, don't do that on-- JAKE: --on a phone. SURMA: --on an Android go phone. That's going to take-- JAKE: It will melt through the table, and you'll never see it again-- melt straight through to the core of the Earth and will kill us all. So definitely don't do that. But what if I told you with less than five minutes of effort I made it into 400 milliseconds-- 50 seconds down to 400 milliseconds. SURMA: Two orders of magnitude less. JAKE: Is that right? Yes. SURMA: I think so. JAKE: Yes, I suppose it is. And I didn't cheat. I didn't delete anything. I actually-- I did some stuff. I didn't break Control-F or Command-F like searching in the document. I didn't break linking. I didn't break SEO. And I didn't even write any JavaScripts, and I'm going to show you how I did that. So, OK, all I did to achieve this is some minor HTML changes and a little bit of CSS. Specifically, these two bits of CSS, which are new in Chrome 85-- and it's only in Chromium browsers right now. But the changes I made don't break things in other browsers. They just don't get the optimization. SURMA: And so you're just applying this to whatever because the HTML spec totally uses whatever. JAKE: I will show you the correct class name I used in a minute. Steady on. SURMA: All right, fine. JAKE: I could have used whatever because I don't think it uses whatever already in the HTML spec. Maybe-- I don't know. I don't know. But before I tell you the class name I did use, that can be-- that's the hook that's going to keep everyone, isn't it? Like, they're eager to see what class name I actually used. It's going to be disappointing. But before we go into detail, I'm going to show you a little bit of background. The browser tries to be smart, like when it displays a page, it doesn't paint everything. It just paints the stuff you can see. SURMA: It seems like a pretty sensible assumption. JAKE: Yeah, it's great. And that means it saves loads of CPU, GPU, and memory by just painting stuff as you get to it in the viewport-- as you scroll up and down the document. But in order to figure out what's inside the viewport it needs to know the layout of the page. And CSS is great, right. You can do anything in CSS. One of the things you can do is take something that's right at the end of the document, and make it appear at the very top. You can take something which is nested in 100 divs, or elements, or whatever, and you can move it outside of those elements. So generally, you need to do all of the layout before the painting. SURMA: Even if you figure out that a box is completely outside the viewport, it doesn't mean that you can make any assumptions about the children inside that box. JAKE: Yeah. Exactly. Yes, it's difficult to lay out just a small bit of the documents-- until now. We have a solution for it now. Here's the HTML spec in terms of how it looks-- in terms of HTML. It's pretty flat. It's a pretty flat document. There are 22 H2 headings. Here's the bit you wanted to know, Surma. You want to know that class name. Here it comes. I wrapped each section in an element, and gave it a class. There it is. Enjoy it. And that's all I did. And of course, I used a regular expression to do this because it's a quick hack, but it worked. It's fine. SURMA: So I was saying you parsed HTML with regex. JAKE: Yeah. Yeah-- SURMA: Dun dun dun. JAKE: I just search for those start headings and those end headings, and I did a-- I did the start and the end tag at the same time, and then just went and deleted the first end tag because it doesn't-- Yeah, you know, it's easy. It's fine. It's OK. It's a hack, but it works and that's the important thing. And then it's the CSS. All I added is content-visibility auto. This is one of those new bits. And what this says-- this says the-- it's like a declaration that says the inner layout of this element can be deferred until this is in the viewport-- until the parent element's in the viewport. And that comes with a few restrictions. It means you can't-- SURMA: I wish they call it deferred now-- content-visibility is deferred. JAKE: Yes, that would make sense, wouldn't it? Because we already have deferred for scripts and things like that. SURMA: Oh, well. JAKE: Or actually for things that enter the viewport, we call it lazy, so I guess it would be content-visibility lazy. SURMA: That would also be good. I like it. JAKE: If we're going to have a spec meeting now, let's do it. Let's change the whole thing. Let's unship it. We'll fix it. We'll fix that one word. OK, yeah, fair enough. The word is auto that it shipped with. And, yeah, that comes with some restrictions. It means you can't paint outside the elements, which you'll be familiar with if you've used overflow hidden before. And it also means that layout can't escape the elements. So you know CSS has collapsing margins. This means you can't use those. It's basically like, that's position-- that's overflow hidden as well. SURMA: Yeah, so by me, the developer, saying, I'm giving this element content visibility auto, I'm basically opting in or guaranteeing that there is no escaping elements that would make these layout calculations actually difficult. JAKE: Yes. Yeah-- SURMA: Gotcha. JAKE: So that means that if this parent element is going to be at the end of the document, that declaration means that the browser knows that something inside it can't drift its way to the top of the document and be in the viewport when the parent isn't. So, yeah, that that's the sort of guarantee that you give the browser and it enforces that-- very similar to overflow hidden. This often leaves the elements at 0 height-- like the height of an element with no children elements. And that's a problem. Because that means all of our sections are going to scroll into view at the same time because they're all just stacked on top of each other, 0 height. Which is not good, because that means they're all going to layout at the same time. So to work around that-- SURMA: Because now they're back in view with 0 pixel. OK. JAKE: Yes, this is contain-intrinsic-size, which, I don't know, it's-- SURMA: It's a mouthful. JAKE: --a difficult one to remember because I always think the first word is content because the other thing is content. Anyway, doesn't matter. What this lets you do is set the width and height of the content of the elements while the layout is deferred. So it's like a fallback width and height, but you are setting the size of the content, not the elements. And this is something that took me a while to get my head around. So it's as if it has a single child element of this size. SURMA: Well, that would only make a difference when you have padding, right? Otherwise it would be the same. JAKE: No. No, so it's different in this case because I've given it in a inner width of 1 pixel there, but it's still going to be a full-width element because that's how block-level layout works. SURMA: Because it's display block-- right. OK. JAKE: So that's why I put one pixel in there. Thought, well, it doesn't matter. And for the height I just guessed. It was the biggest number I could think of at the time, so I just put that in. It doesn't matter much because it's just a fallback. So when it does the proper layout, it's not going to use those numbers anymore. It will give it the correct number. SURMA: All right, so you basically-- let's say you start at the start of the HTML spec and you have a table of contents in view. That means all the actual top-level sections will be empty boxes with a height of 5,000 outside of the viewport, and the browser can skip layouting all the actual children. Because you know what, don't bother. Just assume that once you've layed out the children, 1 pixel by 5,000 pixel is the result. And now when you scroll towards the next upcoming section that's where the browser goes, wait this is now actually very close in viewport. I'm going to the actual layout, but just for this one following box. Which might mean that this section could be larger or smaller than this 1 pixel by 5,000 pixels, right? JAKE: Yes. Yeah, the actual layout could be-- yeah, it could go either way. SURMA: So could that cause problems? JAKE: There is one side effect of that, and I will come to it in a minute, but largely no. It's OK. But yes, like you're saying, the browser can keep the layout really, really simple. And it isn't till the user starts scrolling, and then it goes, oh, I'm going to add that more layout because they're getting close to that element. And it just defers all of that work. But yeah, that's literally all I did with the HTML spec-- just those small changes. And that is what took the layout time of the spec from 50 seconds down to 400 milliseconds-- 0.6% of the original. And like I said, it doesn't break Control-F. That still works. SURMA: That's a big deal. It reminds me a bit of infinite scrollers where, for example, Twitter has these things where you have the tweets in the viewport and a couple of tweets outside either end. When you start scrolling the things at the top will get recycled to be reused at the bottom to keep your DOM count low and keep layout costs low. But those implementations are A, JavaScript-driven, and B, break Control-F. Which I've run into where you try to find a tweet you just saw on your timeline, but because it's scrolled out of the view and has since then been recycled, Control-F won't find it anymore. JAKE: Exactly, yeah, I've run into that, too. When you do Control-F on the HTML spec demo I built for this, it does slow down, because you need-- When you do Control-F, you're not just searching the markup. You're not even just searching the text in the document. It depends on style calculation. It might depend on some layout as well. So it has to go and do a lot of that. And it could do it in phases. It could do it deferred a bit. But to tell you how many matches there are in a document it's going to have to go and do a lot more work than it would do if you were just regular scrolling. But it works, and that's the important thing. And it doesn't break linking either. If you link to an element that's inside one of these deferred layout things, it will figure it out, or at least it will soon. In the making of this demo, I found a bug with that. I filed it. And it's been fixed. So maybe by the time this episode goes out it will all be-- SURMA: That's actually an interesting point, though, because things like display none will affect Control-F and other things as well. That style calculations will still affect the entire document, and will become more expensive the bigger your document is. It's really [INAUDIBLE] layout that gets cheaper with content visibility. Is that right? JAKE: Yes. Yes, it's just layout. Layout's the only thing it saves. But, yeah, with searching for text you can have two elements which are right next to each other in the source-- there's no space between them-- but because they're both block level there is no, as far as humans are concerned, line break between them that isn't in source. Whereas if those two were inline, then there's no space between them. So, yeah, there's a lot of layout information that you need to think of to actually effectively search for text in the document. But, yeah, it's all just taken care of, which is just great. Here's a live demo. Now, you were asking me what might be the problem with me just putting 5,000 as the box size. Watch the scroll bar in the top right. So as I scroll down, there's a little jump there. The scroll bar jumped down. And as I scroll further, and further, and further eventually you get to another section. And it jumps up. And this is it switching from its imagined fallback layout to its actual layout. And it has to adjust the scroll bar to the account for that. But that happens on mobile platforms already for the same reasons-- that you guess the height of certain elements and the scroll bar moves around and adjusts itself as it figures stuff out. I think it's fine. SURMA: Yeah, it's really a question how much scroll bar consistency or inconsistency in this case is a big deal. Because infinite scrollers have the same problem to an extent. And I guess it becomes a lot weirder when you load a page with an anchor that you start in the middle of the document, and you scroll up and the scroll bar jumps back down. And I guess it still works if you click and drag. It doesn't break clicking and dragging the scroll bar itself. That still works. It probably behaves a bit weird, but it should still work. JAKE: Yeah, it still jumps around, but it doesn't break the mouse interaction. It just looks a bit weird. But, yeah, that already happens on mobile platforms. One other thing in that demo-- I don't know if you noticed over the Hangouts call we're on now-- but there was a bit where it was a flash of white. Well, not a flash of white. It scrolled into a white area and it took a while for it to draw a bit. And that's because, like I said, there's 12 headings in this massive document. So I only have 12 sections. And so I scrolled into an area where it actually had to do quite a lot of layout work to be able to render it. And you could see that. I could fix this by just making smaller chunks. So that's one thing to think of as a developer with this is the number of chunks. More is generally better. If you have too many at the start, then you increase the upfront layout work where it figures out where all those chunks are. But if you have too few, then you risk that thing where scrolling to a particular area is still going to be quite expensive. Another effect-- SURMA: Could you nest content-visibility? Now you have the top level H2s that are now all content-visibility auto with their intrinsic size. Could you now apply the same mechanism to the H3 headings, so that the stuff inside the H2 in itself again uses content-visibility to create those smaller chunks? JAKE: Yes, you can do that, and it all just works. SURMA: Great. JAKE: But that's why it's complicated. And that's why we had a bug when it came to linking to a specific anchor through the document, because it knows that anchor is inside this box. So it scrolls to that box, but then it has to layout. And then it realizes, oh, no, that anchor is now somewhere else, so it scrolls again. And then it might have to re-layout because of all of these boxes becoming visible that weren't visible before. And that's the bit that we hadn't done. That's the bug we had is we were only scrolling to the fallback box and it was-- SURMA: The initial position. Yeah, OK. JAKE: Exactly. Another nice effect for this is the time resizing. So resizing here is super smooth because there's not a lot of layout work to do. So it's nice and quick, and that will be quick on mobile, desktop. We compare it to the real HTML spec. And this is an extreme example, but it's taking over 10 seconds sometimes to figure out the new layout for the new width. It really lags behind. SURMA: I mean, you say it's an extreme example, but using this bigger document on a fast machine like you're using is probably somewhat representative of a normal-ish document on a low-end phone where you go from portrait to landscape. That could still happen, and there would still be benefits to making those operations faster. JAKE: Yes. Yeah, and even in some cases-- popping open a keyboard in and out is going to change the viewport size to some extent. So, yeah, this is an extreme example. But have a look at your site, and have a look at the layout time. And if you're hitting a large-ish layout time-- I'm not saying like 50 seconds. If you have three seconds of layout time, and if a lot of that is content that's out of view of the viewport then there's a quick win right here. And you might not even have to change any of your HTML because you might have those sections all boxed up already. So you're just adding like two lines of CSS, and you can knock seconds off your layout, and even if you're knocking just a few milliseconds off. It's almost free to do it. We've had sort of CSS containment stuff in the browser for years. You've been able to do some of this stuff, but it's been such a lot of manual work. But now, couple of lines of CSS, job done. SURMA: I actually would love to see this in more blog templates-- just built in by default-- where this seems to be the perfect application. Which is when you have a lot of text content potentially, just don't layout the stuff out of view. It's magic. It's great. JAKE: Yeah, and not just blogs. We'd see, particularly the news sites that have lots of-- especially on their home pages-- lots of complicated layout stuff going on-- quick win right there. SURMA: Right there. Free performance. JAKE: And that's all I've got. SURMA: Well, thank you, Jake. JAKE: You're welcome, Surma. It's been a pleasure and an honor. And we're out.
Info
Channel: Google Chrome Developers
Views: 23,343
Rating: 4.910543 out of 5
Keywords: GDS: Yes, Slashing layout cost with content-visibility, slashing layout cost, content-visibility, CSS, HTML, HTML spec, content visibility, new videos from Chrome, Chrome, Chrome Developers, Web, Chrome devs, developers, Google, tech, tech videos, web, videos for developers, Jake and Surma, css, javascript, performance, new in tech, new in web, new in chrome, layout costs, web layout, HTTP203, Surma and Jake, Google tech
Id: FFA-v-CIxJQ
Channel Id: undefined
Length: 18min 13sec (1093 seconds)
Published: Tue Oct 13 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.