 Hello, and welcome to the Super Judge Q&A. I'm Paul. And I'm Surama. Yes. Now, we get questions on YouTube, on Twitter, all sorts of places. And this time we're going to answer just the one question. And you've chosen it. Which one did you go for? I chose a question that I thought was interesting because it has so many layers. And it is, what's the best way of injecting new content on scroll because layout is expensive? You see what I did with the layers? Yeah. Dude, get a scroll. Sorry. Yeah, no, the person's right. Injecting content is expensive on scroll. Two reasons, right? You're scrolling. So you've got an animation. And so you want to keep everything nice and fluid, 60 frames a second. And then you basically trigger layouts and styles and paint in one go by attaching content to the DOM. So I totally get where they're going for or what they're going for. The first thing I thought was to use something like containment. But that's only going to be Chrome 52. And it's not available everywhere. But you'd be able to be like, the thing that's having content injected, you'd be like, contain content or contain strict. And then at least the layout and paint and so on, all those calculations are at least locked into that element. But I know that you've been doing some work recently with some Chrome engineers on an infinite scroller. So why don't you explain what's going on there? So layout is expensive. But it's also something that you can't really get around. Like when you attach something new, it will has to be layouted into your document. Otherwise, the browser won't know where to put it. So another approach to basically keeping the cost down is to just keep the number of elements that are in the DOM low. Right. So yeah, because we've seen this before with recycling views basically on native. This is a fairly standard thing, like just kind of recycling them. OK, so that was one thing that we did that basically we keep only the elements that are actually on screen and a little bit on the top and the bottom when you scroll up and down. But basically, the further out you go, there's not going to be any elements anymore. We just use the space with an empty element instead of having all the actual content up there. So you still got the recycling, which is going to trigger layout and paint and all those things. But by the sounds of it, by keeping the DOM count low, exactly, you basically. It is fast enough. Fast enough. As in fast enough on mobile or just fast enough on desktop? Both, actually. That was one of the targets. It's actually fast enough even on mid-range to low-range devices that they can keep up with the work. So we'll have the smooth scrolling at 60 frames per second. OK, so the other question I had is, I know it does some tombstoneing. So explain, at least for me, again, what the tombstoneing thing actually does. So tombstoneing is this technique where because you don't have your data yet. In this example, you're actually emitting a network source where we get the data in that we want to show. But sometimes people scroll that fast that you have to be on screen, but you don't have the data yet. So instead of putting nothing or janking or blocking, we put a tombstone, which says there's going to be content here, which is something that Facebook actually does prominently when you open the app, where you just show here's going to be a post and show empty lines with no text, just gray boxes. And once that arrives, it actually turns into the actual item that's supposed to be displayed. And we do the same thing. So when the user actually scrolls too fast for us to keep up with, we instead of attaching nothing and not being able to scroll, we attach tombstones. So that allows us to keep the scroll going, and then we take care of staying in the same position once the data arrives because the element could grow because it is an unexpectedly large amount of text or there's an image in there, all these kind of things. And it makes the user experience very smooth. So one of the other things that occurred to me about this was it sounds like that prioritizes the scroll above everything else, which is absolutely crucial thing to do. It's like, that's the interaction that the user's got. Yes, they want to see the content, but they don't want you to get in the way of the scroll because that feels awful to people. Do you use anything like request.idl callback to make sure that the main thread is available for work before actually spending time trying to populate the data set? Or is that not something that gets done yet? We emulate a fetch. And once data comes back, we check. I don't think we use request.idl callback in the demo, but we check if the element is still on screen, if it even needs to get attached, because if it's off-screen already and the user has been scrolling so fast, there's no need in treating the layout and then removing it again, because it's already way off-screen. So that is the kind of booking. Request.idl callback would be great, though, if we know that we are on-screen, but maybe the browser is still busy with decoding a fetch request or something. So it would be worth decoding that first and way down to the browser is actually available to attach the data to the don't, or replacing the tombstone. All right, cool. So basically, I think in summary, it's like, avoid it if you can. If you can't avoid it, keep the cost down, and then basically be really, really tactical about the work that you do, either by checking that the thing is still in the window and still needs to be dealt with, or maybe even considering some other request.idl callback. Only to do work that you really need to do. That is one of the things I learned with this. And also, really important, I think, is always test on a real device. Like, we have emulation mode, which is good to see if layout works, and you can even throttle down the network. And I think in future versions of Chrome, you can even throttle down the CPU to emulate a slower device. But nothing is going to tell you how weird it really feels. Once you're on a RAM constrained and CPU constrained device and realize, even though it works fine on desktop, on mobile, you're way below 60 FPS, which we had a couple of times with this thing. And it's just a completely new experience if you're actually on a device. OK, well, I guess that's it. Like we said, basically, avoid the work when you can. Performance is the art of avoiding work. And if you can't avoid it, keep it to a minimum. So with that, I guess we'll catch you next time.