This course has been updated! We now recommend you take the Introduction to Dev Tools, v3 course.
Transcript from the "Page Jank" Lesson
[00:00:00]
>> [MUSIC]
[00:00:04]
>> Jon Kuperman: Page Jank, we've talked about it a little bit, just like this general according to Jank free. It's a stuttering, juddering or plain halting that users see. So it's pretty common and it's one of those I think like subtle things that makes a big difference to the user experience.
[00:00:21] Like any kind of like stutter, I mean it just kinda throws you off. It just doesn't look great, it doesn't feel great, and they've done a lot of market research studies that say that, it's very, very important to people that websites are apps feel fluid, feel really smooth, feel instead.
[00:00:36] So this is why I like measuring frames per second, and looking at the timeline for Page Jank notifiers is really important. So this is kind of an older view of the DevTools. But paints are definitely unavoidable in the sense that your screen needs to paint any time anything needs to change.
[00:00:55] But there's a lot of stuff that you can do to make the process better. And so we kind of covered 60 frames per second. Again there's just the math behind it. Basically, a new frame 60 times in a second which gives your browser 10 milliseconds to come up with a frame.
[00:01:10] And so some kind of like interesting things that you can do coming back over here. If I open the DevTools, well it's got really big on me. So there's a kind of hidden panel that's not one of these panels. And it's accessible only by hitting the Esc button.
[00:01:29] And it's called the like console drawer or whatever. I use it a lot because it allows you to have a console on every other panel. So if you wanted it instead of hopping between elements and console like we were doing earlier. From elements you can just hit Esc and open up this drawer, and you have your full console access.
[00:01:45] But it also offers these two tools around Animations and Rendering. So the first one that we're gonna use is a FPS Meter. You turn that on and all this and you get this fancy little frames per second thing going on. And from there you can kind of go around on your site and you're just basically seeing like if it's moving, so it's cool, it's color codes it all for you basically.
[00:02:13] Basically like as we get up higher and higher and higher, it'll start turning orange and then red, if you're not able to serve enough frames per second to the browser. I'd also tells you like how much of GPU memory is being used. This is like if you're doing any kind of D3 or even like just complicated CSS animations.
[00:02:32] It's really great that you can toss work to the GPU, but this helps you kind of keep an eye on. If you're close, because the GPU only donates so much to your browser. So you can you can max that out, doing things like CSS transitions and animations. This is pretty cool.
[00:02:49] The page that is here definitely feels a little bit janky, but it's not breaking the FPS, which is good.
>> Jon Kuperman: So yeah, I guess, okay, so the FPS Meter is really nice and I leave that up, sometimes. The other thing that's really, really useful is back in the exact same area is Paint Flashing.
[00:03:13] And it's called show paint rectangles on Chrome stable they just renamed it and what this lets you do, it works nicely in Tandem. Is it basically will flash green wherever the screen is repainting. So you knew this unlike any site to get a good idea, this is where I think you asked a question about like, how can you find what's causing, like if I see a lot of paints or a lot of rendering slowing it down.
[00:03:35] It's not as easy as clicking a function a line number, but what you can do is you can turn on Paint Flashing, and you can see where your problem areas are. So it looks like I have a problem area on my whole page, but I also have an additional problem area on this little ad that I've got up here.
[00:03:51] So this kind of helps you visualize things. An area like that's interesting to look at like on Twitter, I worked for a while on the Home Timeline. So I'd have Paint Flashing on and nothing should we rerender, right? The entire time line, if something needs to change it should just rerender it.
[00:04:06] So it's like those are the kind of things that you would watch out for with Paint Flashing. Your whole page should not be repainting, unless it's actually changing all of its content. So we can see that we kind of some problems on here, if we wanted to see a good example, there's this really adorable site called koalastothemax.com, I think I have a slide for it.
[00:04:26] Well there it is, we'll get to it, but we're gonna jump to this. So you can turn Paint Flashing on, open up the console, open the drawer, turn Paint Flashing on. And from here you can see what a good example is where all that rerenders are the actual areas that you're changing, right?
[00:04:42] So what a bad example would be is if we saw this whole square paint green every time we just animated something over here. So this is what a good example would look like, and I think if you scroll enough on this it turns into a picture of a Koala eventually, it's gonna get there.
[00:04:59] Anyway, there it is. So yes, so this is a good example, this page that I have up right here is a bad example, cuz we're seeing way too much stuff going on here. So this one again, the painting and rendering is trickier to diagnose than JavaScript stuff, right?
[00:05:18] Like the JavaScript stuff, we can just click on and get a line number. It's pretty easy to at least find what the problem is, if not find a solution. The painting stuff is a little bit trickier and I often use this kind of find and delete methodology. [LAUGH] I call it, so basically, I'm gonna pin this to the bottom and I'm gonna close the console door with Esc again.
[00:05:38] And basically what I do, pretty frequently is I just kind of hover over items. And then I use the Delete key to remove them and see if the problem still exists. It is very scientific. So for example, if I see that the first problem that I wanna fix is the whole screen is repainting when you scroll.
[00:05:59] And there is just no reason for that. So it's like if I kind of went in here and I started just a fleeting items, I got in that row and then it's OK, that's a bad example. So I can Ctrl+Z to undo, cuz the rows all the contact.
[00:06:12] But anyway, so you can start sniping, get rid of this class here, and see us still problematic. And then you can kind of get rid of the stuff here, again it's shrinking the content too low. But anyway, it's kind of the best approach that I found so far, is just removing it.
[00:06:27] I mean sometimes it'll be obvious, right? So in this case, I have a pretty good idea like fixed position items like this, are always a pain. They're usually a source, so what I imagine is if I go ahead and inspect this thing and it's like this ad-container. And I go ahead and delete it, we won't see that extra junk anymore.
[00:06:47] Now we just have the one covering the whole page, right? As opposed to before, we've got two. So I know that the fixed position is a problem, but if I'm not sure what the problem on the actual page is, I usually just go through and delete things. So this is an example that I took from somebody site, where they have this div menu animation wrapper.
[00:07:08] And it basically was just like a container that they had that they wanted to use as a CSS selector. So it was an outer container for everything, but it was styled all wonky with this position fixed width 100, height 100, z-index 1,000, all this stuff going on. So I took this overproduction site.
[00:07:30] And it's really useless, cuz all it helps with is your CSS selectors. But if you go ahead to lead it, then all of a sudden there's no more green on any of that page jank. So that's why Paint Flashing is so important, cuz it's some seemingly harmless thing on a container.
[00:07:44] Can actually be causing users to visually struggle to get through your site. Another thing that I just kind of want to talk about with screen paints is, this is from, I can't remember his name.
>> Jon Kuperman: I'll have to look up, I think I've got the source somewhere. But this is really, really great blog post that's called Preventing Layout Thrashing.
[00:08:10] And it explains what it is that causes things to need to be repainted too often. So the basic idea is whenever you write to the document in any way, the browser has to invalidate that containing layout. Cuz it can't possibly know what's being changed as you write to the document.
[00:08:27] So the problem comes not writing to the document, cuz that is important you always need to do that. The problem comes with the way we end up having to structure our code. So we do things like this all the time, where we read something then we invalidate it.
[00:08:40] And we read again, then we invalidate again, cuz we're reading and writing constantly, and applications are really big. So what it would be ideal to do is to do all of our reads, and then all of our writes. Which is just not realistic in a real company with multiple employees writing code.
[00:08:56] You can't be like hey, you now allowed to look at the height there, you have to look at the height in another file and weigh up the chain, it's just not possible. And so what you can do to avoid this layout thrashing, which is the constant invalidation of the DOM, is you can use this API Window requestAnimationFrame().
[00:09:15] And requestAnimationFrame() is basically a method that gives you a call back. And it says, hey, next time you're about to repaint anyway, here's some code I want you to run. So you could say, if you need to write a user's name or maybe it's a shopping cart, and they're clicking on items they wanna add to their shopping cart.
[00:09:35] So every time they click on an item you need to update that total, right? We don't necessarily need to do it instantaneous, I mean you get 60 frames in a second. So instead of writing to that shopping cart, you could say, Window.requestAnimationFrame() you can pass in a callback function that writes the shopping cart.
[00:09:52] So it's doing things like that will really help you. But don't worry, you don't need to do all that stuff yourself. I just wanted to explain how the inner workings of this really cool library. Wilson page, he's the one that wrote the article, this library's called Fastdom. This is a library that you might not be familiar with, but likely libraries you use have this as a dependency.
[00:10:12] So it's at github/wilsonpage/fastdom. And so all this does is it has a nice little API that just wraps everything in these nice requestAnimationFrames. So you write your code kind of normally, and then it takes care of making sure that it batches up reads and it batches up writes.
[00:10:30] So I'd recommend using this, it's very easy to use, but likely if you're using something like amp, amp uses fastdom. If you're using, you know what I'm saying, it's usually a dependency of your dependencies. But it is a cool concept and I want to explain how it worked.