 Hello everyone, I'm Sam and Paul we're talking about performance and We're gonna reconsider kind of how we fix poor performance. Oh, well, this is really timely for me. Oh It is this this talk. Yeah, because last week I was looking at a website and it's like I think my website's kind of slow Sure, it is love. It feels weird and I wasn't sure What to do to really fix that like bad load, right? So I did The normal thing I think that we all do I went to Google and I looked up your email address. Okay. Sure. Okay. It's fine. And then I I sent you a message Paul I need your help right And then you didn't respond yeah So that was rough, but it's okay. It's okay. Cuz you know, I was like I am going to fix this myself Yeah, yeah, so I went to Google again, and I I typed fix slow page load time and I got like all these results on Google. There was like these top 10 lists top five There's a lot of things and I think we all know this like when it comes to performance there's a million techniques and we kind of keep them there in the back of our mind these checklists and Well, it's hard to know like what's effective or not So actually we wanted to turn this into something a little bit more interactive turning it into a little game So we're gonna play a game. It's called factor fiction perf trials and You said it wrong said it wrong. Yeah, remember we practice this Okay, so we're gonna play a game and it's called factor fiction Perf trials So this game it's pretty pretty pretty good and you're gonna participate like this you can go to this in your browser your phone laptop whatever and We're basically gonna try out a few different leno techniques for just make a website faster and we want to get your Idea on if what we're gonna what we're doing is gonna be effective or not Yeah, like is it gonna have a lot of impact or not So you can just use the slider they have on your phone and drag it up or down Here, let's everybody practice. Everyone go up. It's like positive. Oh, it worked. I'm gonna go down Man, this is like like the wave. It's so good future. Okay, cool Come all right, so the website that we're gonna be looking at it's actually your mom's website So my mom is an author and I was building a new website for her this summer And it's WordPress. Yeah. Yeah, it's a WordPress site like it's a it's a really just like The kind of site that you end up with Like normally so just a bunch of like plug-ins for for events and things like this and but I didn't like do any optimization to it Yeah, so we're gonna take this as our baseline site and see if we can make it faster Sure, so let's just get a feel for what this site is like when we load it Yeah, so if we go into DevTools, and we just turn on 3g throttling to emulate what it's like on your phone And yeah, let's just load it. Okay, so it's going Okay seems I'm not terrible seems okay, there's room for improvement There's an opportunity opportunity. That's what we like to call it Okay, so I recorded it using the network tab and it looks like our final load event happens in around nine seconds We send out 39 requests, and this is on again like a 3g network. Yeah, okay, so that's where we're starting somewhere sure So Fixed number one that I found on the internet Yeah, people seem to think that bundling all of your JavaScript together was a good idea So taking all your individual JavaScript files sort of catting them together in one file and then shipping Okay, so this is just like all the scripts and you can cut into one file pretty much Yeah, so what does everyone think it's just like gonna be a improvement to our page load time or gonna hurt it It seems like it's working so yep. All right, so I did this And our load went nine seconds to eleven point seven But it's just been cutting which is like less requesting the good thing. Yeah, we want the slow requests. We made it slower Interesting and so we we looked at this some more and it turns out that since we're shipping one JavaScript file on like Versus lots of individual ones and sort of pushed out that initial paint time right quite a bit because you'll just have the One big render blocking request and now it's a very sizable thing in the download especially in a throttled environment Yeah, it's not so good. Okay, so thumbs down on that one. Yeah, unfortunately Fixed number two you told me about this one add the deferred Yeah, so defer attribute Kind of like the cousin the brother of the async attribute But a little different it does basically the defer is essentially a contract saying I'm not using document right in the script But in addition to that it allows the browser to continue to parse Itch email as it just continues on the page and you usually end up they are with like a faster thing and Do you guys think it's like an improvement? Gonna help at all with our load time It's climbing up. Okay, I'm gonna say people think it's an improvement So flat flat flat flat just nine seconds Okay But you know the internet has lots of lists and there are more options for good. Okay, great fix number three Group the style sheets together in the head above script tags The idea is that you put your style sheets above any script tags because the browser can only send out like six requests at a time Yeah, yeah, yeah rest. Yeah, so like you wouldn't want to interleave because Style sheets are gonna be more important when it comes to like the rendering what things look like So if they're the most important things you want them to be the first things to start because if there are a lot of Requests like there are 40 on this page They were gonna hit our maximum of six requests per host name ten requests total and then like all the next request get queued I'm just like I have the spec reading to me right now. It's actually The this behavior of six and ten is unspecified. However, all browsers do implement the same way So Today I learned. Hmm. Thanks, Paul, right? There you go Okay flat again flat hmm Seems like everyone kind of agrees with us. Just like this doesn't really do much. Yeah, I mean Was the like did the load just change in any way, you know, it was interesting when I did this I sort of saw this like flicker of like half pane of things and then it snapped in again And so it definitely affected something but our load time didn't really move at all. Oh, oh interesting. Yeah Okay. All right. Yeah, one more fix number four. I really like this one Minify our JavaScript in CSS classic So you something like Aglify and like my UI compressor for our CSS and shrink the file size and then send it down Oh, wow people are reaction really thinking this is good. Wow. It's really going up. Okay. I Mean Yeah, yeah, it's less bites. Good. Hey, okay. I worked and yeah, it did something so we're down to 7.6 seconds on that load Thumbs up. That's pretty solid. Yeah. Yeah, and this is without any of the other fixes We just minified the sources. So we're still shipping the same number of files, which is like 4039 cool And it dropped us like a lot. It's good. What if we took all of them and we put them together Good question. Okay, so all four fixes at the same time like What do you think effective not like it would be more effective than then fix for on its own No somewhat positive positive Okay Turns out we basically hit the max when we did the compression of the yeah I just like Largely better than than the minification that we're just looking at yeah So it took like the best case load time that we had and Shipped less requests So, okay, I mean we had an improvement. Yeah, and in fact before we move on This is the end of the interaction, but can you get that off the screen? Oh Thank you. I guess before someone figures out how to you know send the messages Yeah, let's open up the console and Real quick. Okay. Okay. Good So we were using on load as like our just measurement of the metric that we're just like for all those yeah, right but you're also point like On load is kind of a crude metric you were pointing out that in the style sheet one you actually that number didn't change But you saw things were rendering Like starting a little bit earlier even though it ended at the same time, right, right? So like there's this question if we're really trying to evaluate the load time like Can we use something a little bit better? Like can we use better metrics than? Than on load and so Sam and I have worked on a project with some other folks called Lighthouse Lighthouse does a lot of things it does auditing for best practices of web development And especially around progressive web apps, but it also does a nice job of measurement and delivering high-quality performance metrics And so this is just a screenshot of what Lighthouse looks like on the command line So it's available just on the command line you can run in continuous integration But also in a Chrome extension and a few places node module like we use the node module. Yes Yeah, so actually we took the node module and then just put like a little charted Module in front of it and a little tool called PW metrics and so just pass a URL It runs it through Lighthouse takes the numbers out plots them and these are all like more meaningful metrics for us When we're trying to measure this page loading and when it's interactive when it paints and when a user can start to sort of use the site Yes, actually exactly. So we ran this on the site with before and after so top is before the baseline No changes at all and the last one is this with everything. Yeah So you can see that we shrunk that time to interactive which is basically when the user can start using your application Yeah, and in this case the website So we went 3900 milliseconds to 3300 so it's faster 16% faster. Yeah, it's not bad That's yeah, it took some techniques that we found online and we applied it to this very specific site Yeah, we did get some wins. Yeah, totally But also like just going through this I just kind of wondered I'm looking at it You know 16% like that feels good and that's that's that's worth something But also like how fast could it be like are we anywhere near close to like bottoming out at like the point of diminishing returns or like plenty of room left and so Like the way that we did this was we just basically take these techniques that we saw Try them out. Yeah, if it works reload the page like it seems faster. Maybe try some more Yeah, you just keep stacking and so I want to like think about what if we could kind of invert that process instead of Just going right at it and applying fixes kind of what if the fix is the last part that we do so Starting kind of the first place what you really want to identify is the the user perceivable effect now here We're talking pretty much about just page load right and just that kind of narrative of going from a blank page to Things on it But we could be talking about scroll input latency other directions like that After that you want to kind of look at what is happening identify that kind of the critical path And figure out what is the primary cost? What is consuming time? From there you're gonna like you like something looks interesting. It looks like there's some behavior That's a bit unoptimized. Yeah, like the cost is going to be because of a reason So you're gonna drill in and ideally you're gonna find the reason why it's slow Yeah, and so the reason why I slow is is the root cause I mean like this is the thing at that point That points a good time to try and apply some fixes So we kind of just go through the measuring and profiling diagnosing identifying and then we attempt some fixes And then we're in a good place. I like that. Let's get like you measure your profile. Yeah, no It's like a mip dia. It's like mip dia. Mip dia. It's what mip dia mip dia. You measure your profile You diagnose you identify and you attempt. Oh, you're making a name about mip dia. Mip. Mip dia Mip dia, it's the new framework for performance diagnosis. There was rail and that was cool But that's so like 2015 sure mip dia is so 2016. Yeah, totally Right, but you just People are shouting and I hear it All right, it's fun. Well just kidding. All right, so first step in measure in mip dia You need to measure and measuring is important because you don't measure. Yeah, I got it. You can't do the rest Yeah right So we're going to Use this really cool JavaScript API that's shipping everywhere performance mark and measure Yeah, what this is gonna let us do is actually in our JavaScript code put these performance marks So we'll be able to say this is when I'm instantiating this jQuery plug-in. This is when this view shows This is when I fetch the data and this is how long it takes And like yeah, so it requires a little bit of work and go in and instrument your code But it's really useful to be able to talk about times and durations and things in your terms rather than the browser's terms and so like we applied it on on the site and so in addition to just getting the information out in the Jockline side JavaScript it also kind of augments the Chrome DevTools so in the timeline, you know You could kind of look at this flame chart and like try and diagnose what is actually happening here Or just kind of look up at your performance measure because everything's kind of labeled here Yeah, so I mean this is this shows up right in DevTools, which is really handy when you're trying to profile What exactly is taking a lot of time? So Should we profile this? Let's give it a go. All right. All right, so I'm bringing up the site and we're going to go look at it over in the timeline Let's see. We'll keep on network JavaScript profile screen shot 3g network still enabled cash disabled 3g. Yep. Yeah, all right Reload When you hit command R here, it's going to reload and it's going to wait until Three seconds after the unload event fires and then it will just stop recording automatically But if you want you can just stop it yourself Pro tip Sam for you. That's a nice one. Okay, so This is just the overall look of everything that's happening. That's a lot of network requests Yeah, yeah, exactly. So we got a lot of network requests all up in here the purple requests are style sheets and these guys are scripts Images here those go out quite a ways And then down here is the main thread Here is those marks good stuff. So there's a little bit of job script activity down here, but yeah, a lot of Lot of network action So we're really looking at like when do we paint something on the screen because that's what we want to optimize, right? Exactly. So okay first step measure Really so we can just drag this and kind of see the film strip of screenshots and the first paint is right in here Right when we get that painted and then later images in two seconds. Yeah, so we're at about two seconds here And if I just kind of zoom to that area, all right down here main thread Not doing a whole lot. Yeah, it seems pretty empty Which is like confusing because usually you see a lot of stuff there and that's what's preventing the paint right in this case We're not really doing much JavaScript, right now. I will point out at the end over here this stuff If I actually just zoom in a bit We do see a recalc a recalc a layout Green guy And that is actually our first paint And so that's our first paint. That's nice. He's right there. That's nice But so it actually here's so what I want to do at this point is Make this paint happen sooner. It seems like we should be able to push that way back So it's not at twenty six hundred milliseconds for our first frame. Yeah, okay, so optimize first paint. Yeah, it's our goal Now the thing is there is actually a relationship between what's happening here and the stuff up here And check this up. It's kind of kind of cool. So I'm just holding down shift to get this little selection But if we look at when this paint happens, what just finished? Oh jQuery Yeah, actually. Yeah, so check it out. So jQuery.js. Sorry about that. Wait, so you you you have like commits in jQuery, right? Yeah, so it's basically your fault on your own website That's nice. We'll fix it. He'll fix it. Yeah, thanks Okay, so so jQuery just does finish and actually this is the reason why I remember with a concat Remember how can catch right lower? Imagine that like these all these other scripts are also just tacked on so this one request is much bigger, right? I like that sound like that's what I imagine That's the sound of the network. It is the sound of that crazy. Okay. Now. The other thing I do want to point out here is Only little tiny red squares. That's usually like it's important. Yeah, it's actually the network priority and A medium higher highest network priority is a pretty strong indication that it is render blocking Now that's not like 100% of the time, but generally that rule works pretty well. So render blocking Requests is exactly why You can see like, you know, these images not render blocking but pretty much jQuery render blocking the paint render Happens right when it's all jQuery jQuery. The last render blocking request finished. It's fine I know you're trying to like push off the responsibility, but clearly it's Thank you. Okay, so So, right render blocking resources and we don't want them to be render blocking. No, we should like make less things red Exactly. So Now that we've kind of figured that I know where you're going. Yeah So actually first thing that we want to do is take the scripts make sure Take all the scripts make them not render block it. So we're gonna. This was my fix apply. Yes, the defer attribute to all the scripts So sorry, yeah, that's yours Now in addition to the script tags, I'm also going to apply it to do something. Sorry, what I this is so nice of you I I don't have to look up your email address because I just have it right here now. Thank you so much All right, but go ahead. Sorry. Sorry. I don't know why we didn't catch this. Okay. Anyways Style sheets moving to the bottom. So we're gonna move them to the bottom and actually this is pretty cool Moving style sheets to the bottom kind of we've always thought that like that might be better if you don't if they're not super important And since some of this actually changed recently, I'll explain a little bit of what happens So previously and previously especially in Chrome. This is the behavior that would happen like let's say We're just parsing HTML doing some stuff. We find some of these Style sheets in the body. So we kick those network requests off and basically we just wait until all of them are done Downloading and when all of them are done downloading then we do style layout and paint that seems not great Right because these are that we treat them as as render blocking and we just don't do anything So as of this summer Chrome changes behavior and actually falls in line with the rest of the browsers So the new behavior is if we find Style sheets in the body We will kind of like flush what the page should look like at that point and then also when they're done We'll do it again. Okay, so now it seems like it's a good idea to put non critical CSS into your body Yeah, so you get this win, right? So the browser will be able to paint the page at that point, but also like as it moves forward It'll pick and pick them up and apply the rest seems good. Yeah so in this case kind of what it looks like and there's a lot going on here, but At the top we have these purple style sheets. These are the guys in the head now the scripts that we applied defer to Thank you. These are now green nice so they're down here and The style sheets down here. These ones are the ones that I moved to the to the bottom of the body They're down here. So Check this out the paint that we were looking at before. It's right here and If you look We have all these other style sheets, right now before we were waiting till all of these finished and also these scripts too But now like we're able to get that first initial paint out much sooner And then the rest of the size it seems like a major win. Yeah, this is good So pretty good now that we went through this Process like a pretty good win and we go back to measure. Yeah, take another look at just the overview so if we just took a screenshot of The timeline in this case and since we have those Performance mark and measure in there We sort of get a feel for what's eating up the most of your time and what's weird is a slick nav It's like you see So like I zoomed into this stack and It's actually taking on my phone 60 to 90 milliseconds to build this and what this is is the navigation element on the top Yeah, it is it's hidden by default. It's the yeah, it's just the top nav It's just instantiating some stuff on the top nav, which like shouldn't really take a hundred milliseconds seems really weird Right, so that's that's off an alarm bell and then you looked into it. So what's happening? Let's just like go through it here. So In my timeline here what I can do is I can zoom right in to where we're evaluating the slip nav, which is all the way over here and I know because I looked at it before Real quick, I know by looking at it before that a lot of work happens in this plug-in visibility toggle Yeah, even like the force layouts and stuff. Yeah, it's like a whole bunch of work down here How much there's oh because it animates right after yeah, it animates I guess Curious weird. I didn't like see an animation when it loaded. Yeah me either, but let's look at the source code Okay, nope and like I know what this code does is it just sort of hops into this block here Which is calling this slide up right here and adding a class of hidden. So oh is this is just the jQuery Slide up, you know that whole effect So we should get a better idea of what this feels like. So what I will do is we'll just put a break point right here Okay, and we'll reload the page Okay, cool. And so here we are at our breakpoint and you can see that our menu is actually open here Hasn't been let up yet. So here we are and let's just look at what's happening wait, wait, wait Duration zero so that's just the first argument of jQuery slide up is the duration and passing in zero zero But it's zero in a length animation is like no animation like display none but Yeah, but it was doing like 90 milliseconds of work. Yeah, like a whole bunch of it from this tweens and yeah and jQuery deferred objects But so but wouldn't there be like like a fast path where they're like, okay If it's zero, we'll just like yeah immediately hide it and skip the whole like creating animation I agree. I agree that would that seems like it would make a lot of sense. Okay. Um, it doesn't So we're paying the cost there creating the tween Object yeah, and then creating the jQuery deferred wrapper to tell us when it's done Yeah, and then animating it for a zero duration and then and then doing that each time flowing every single menu I'll each time you do this Expensive, okay, so as you would say There's opportunity here to make this a lot better. There's an opportunity So what we did is we just switched it to display none If duration equals zero, yeah, basically fix the entire problem. So that was good straightforward fix So yeah going through this Identifying that height that slick nav was it was pretty costly and it was pushing out this time to interactive Because we really want the main thread to settle down so that when the user you know starts to to work with the site It's available for them and we were able to identify this because we had those annotations. I made it really easy nice stuff So in total we did a few things in this in this case the scripts and the styles are moving them down Also the images I didn't mention this they but they were taking quite a while And so just really basic compression and fixed one the sizing of one really boring and the top one Did apply a link rail preload to get that request going out really really early lastly that slick man that's right, so We didn't do any like bundling and you can cat any minifying And didn't like to figure out what else we can remove from that site I'm sure that all of these things would also have impact But going through this process like these are actually are not the highest impact things for the site, right? So we should look at the results now So this was before we did anything first baseline. Yep, then this was after my fixes stuff pretty nice It's good. Then these are with your Yeah, so a few things to point out the content will paint that first paint where there's actually stuff on the screen That came in quite a bit and a lot of that had to do with the defer and they sink and all that stuff And also, but the time to interactive also slid in quite quite a bit. Yeah, we're gonna drop that a lot Yeah, yeah, we went from 2400 milliseconds to 1500 milliseconds, which is great pretty good This is on a 3g connection to really good And then our time to interactive went from 3,900 to 2700 again really good feels all about that I mean still plenty of more opportunity, but It's a good place to start so okay, so in total a Few things that we are left with Applying just kind of generic performance techniques blindly and just kind of guessing like Expect it's gonna sometimes be better Sometimes be worse. It works that bundle thing. I mean, I did not expect that that made it a lot worse And that's you know, that seems very common to do right so always just measure go through The process of understanding the critical path and and diagnose in that situation before you get into the things Also, the last thing just use great metrics putting a lot of work into Moving one metric if it's the wrong metric is is not gonna work out. Well, so use nice use tools To that help you with good You're missing one like the most important one really missing one. Yeah, but the what? Mip dea Paul. Oh We learn if you don't forget about me. Okay. I'm up. Yeah. I like it. Okay That's it. Thank you guys