Web Performance Fundamentals HTTP2, Caching, and Pre-Loading Practice
Transcript from the "HTTP2, Caching, and Pre-Loading Practice" Lesson
>> The third thing that we can do to improve our LCP is to reduce the overhead. So if we've in our hypothetical example here, we minimized all the requests that we need to focus on just the CSS that we render, and just the images that are above the fold and visible to the user.
[00:00:19] But is there anything that we can do to make these requests go faster? Yes, yes there is. Let's look at what a request is. So when one of these requests happen. At the beginning, if it's a new origin, if we're not loading it from the same place as our document, we might have to do a DNS look up, say where is this image from?
[00:00:42] And then we'll have to establish a TCP connection to them and an SSL hand shake for security, and then we make the request, and the response and then process it. If we had a second image that's also on the same domain, we'd have to do all of that stuff again.
[00:00:59] We might not have to make a second DNS lookup, but we have to do all of those same things. Well, that's a lot of redundancy. How do we do fewer things? One of the best ways to do fewer things is to implement a protocol called HTTP/2. This is supported on most web servers, but not all.
[00:01:19] Unfortunately ExpressGS does not support HTTP/2 yet, but if you're using EngineX or Apache, they're really easy to turn on. One of the many benefits of HTTP/2 is that you can reuse connections. As in, if I'm making multiple requests to your web server, I don't have to do a TCP connection and an SSL handshake every single time.
[00:01:43] I can do it once and ask for all of the documents together. And so I've cut out a big part of that overhead. Unfortunately, you can't always use HTTP/2 practically because even though it's way faster in terms of actually pushing the bytes over the wire. And you can reuse those connections, there's some cons as well as then not all servers work with it yet.
[00:02:08] Not all connections. It's really hard to get node up and running with it. And so if you're doing like a local dev server like I am, you might not be able to run it locally. The other thing that really makes it hard to run locally is that you have to use SSL.
[00:02:24] You cannot have an unencrypted, HTTP/2 connection. As many of you I imagine can a test it is kind of a pain in the butt, to have a local selling certificate and go through that set of hoops every time you want to do Dev work. Locally signed SSL is still, even in 2021, kind of a pain in the butt.
[00:02:45] All right, what other ways can we use to reduce overhead? Well, we can cache it. What if we didn't have to make any of those things, we could just take an image and process it. We didn't have to request it. We didn't have to respond to it, because the browser already had it.
[00:03:29] These headers are cache-control, expires an etag, and they're all necessary for different things. Cache control tells you, how long should you hold on to this file in seconds. So this is saying, hey, for five minutes, this is the image, you don't need to ask for it again you're good to go.
[00:03:48] If you want to be very explicit about it expires tells you exactly when this image expires and do not keep it after that. And to help it further, you can return a hashed version of the object that says, hi, if you ask for it again, and it says the same tag, I'm just going to tell you to use the thing you already have.
[00:04:09] All three of these headers are options that are easily turned on that you can easily turn on in most platforms you don't have to like figure any of this stuff out for yourself. You look at the platform, and the framework and the technologies that you're using and look up caching headers, and there should be easy ways to configure all of these options.
[00:04:27] And these have huge benefits to performance huge benefits, but only for returning users, which is important to know. The first time a user hits your page, the first impression they get, nothing is cached. They're gonna have to pay that price for everything. And so you don't want the first impression to be that your site is slow.
[00:04:50] So everything else needs to be fast as well. All right, there's a third way that we can reduce overhead. And that's what preload. In the case of our CSS files, we have one CSS file that then needs to ask for some fonts, which is super common a lot of sites use like Google fonts, or you have your own fonts to pull down.
[00:05:12] You could also have a CSS that imports and other CSS. Well, we know that we need these things like it's in our CSS file, like we know that we need to get this asset. What if we could tell the browser, hi, go get this thing right away. Don't wait for you to parse all the way through it.
[00:05:31] I'm telling you right now you're gonna need it go get it. We can do that. When we do that, we can pull that forward and start that request right away. And we can do that with something called a preconnect request. So because the site uses Google fonts, I know that we're going to need to connect to fonts.gstatic.com.
[00:05:57] I don't necessarily know what file you're gonna want because Google's can change some things, but I know you're going to want to talk to it. And so go ahead and do your like connection setup your DNS lookup right now. For other things like maybe I have an import of another CSS file I know exactly what file you need and I can do a pre load.
[00:06:20] This is go ahead and fetch the file. Something downstream is going to need it and I want you to get started downloading it early. We can use these things to decorate our page and get started sooner on what we need to do. By doing this, we can further shrink the difference between first contentful paint and largest contentful paint by smashing down that time we're waiting for all the fonts to come down.
[00:06:48] So let's go ahead and add preload and preconnect to our setup. So let's figure out what we need to preload. So if we go over to our Network tab and show everything, we can see here's all the things that need to come down. As we go down here we can see fonts, here's the fonts that are coming down and the fonts are coming down from fonts.gstatic.com.
[00:07:19] So we know we're going to need to connect to that. So if we go back to our HTML document, now we go in the head, because we know we wanna get this thing started right away. Let's add some links. So we're gonna have a link. This is going to be a pre-connect, we want to go ahead and connect to this resource.
[00:07:43] Let's connect to https://fonts.gstatic.com. We also are going to be connecting to, as part of pulling down our website, we have this little chat widget over here, which is connecting from a different origin. In my case, it's just a different port running it's local host Port 3001. But I know we're gonna connect there.
[00:08:11] So we can go ahead and add that too. So we're gonna pre connect to http://localhost:3001. And there's even a CSS file that we have that is being chained. Because Main, we can see in this little waterfall chart here on the right, the main CSS file is then loading the fontello CSS file and the banner CSS file and the index CSS file.
[00:08:43] So we can just tell it to go ahead and preload it. Index.CSS fontello.css, banner.css actually I think fontelo is a battery So all together we added these five annotations to the top of our index. We said that we want you to go ahead and establish a connection to fonts.g static and local host 3001 cuz you're gonna need these connections later.
[00:09:29] And go ahead and download these other things because we know you're gonna want to connect to them, or we know you're going to download them as part of your process. And so the browser can get started on these requests sooner. So we can save that. All those things together.
[00:09:47] We have crunched the amount of things that we've done. And made the smallest possible critical path between first contentful paint and largest contentful paint, we're gonna take.