Web App Performance

Cache Control, dns-prefetch, & preconnect

Maximiliano Firtman

Maximiliano Firtman

Independent Consultant
Web App Performance

Check out a free preview of the full Web App Performance course

The "Cache Control, dns-prefetch, & preconnect" Lesson is part of the full, Web App Performance course featured in this preview video. Here's what you'd learn in this lesson:

Max explains the immutable Cache-Control value indicates to the browser an asset never expires. Using the dns-prefetch and preconnect options in header link elements is also explained in this lesson.


Transcript from the "Cache Control, dns-prefetch, & preconnect" Lesson

>> But more things that we can do. Do you remember from two hours ago that we were mentioning the conditional request. That when you have an asset, a resource in the cache, but it's expired, so then the browser needs to make a conditional request to the server. Well, on some assets, we know that that will never happen.

For example, when you're using React or Angular or Vue CLI, all the assets that you get, the JavaScript, the CSS, they have a hash name. So the name is hashed. We have something like app05d.js. So we know that those files will never change. So a conditional request on those assets will always return, go ahead, the one you have is still valid because those assets will never expire.

Does it make sense? When you know that the asset will never expire, we can use cache-control immutable. It's an HTTP header that you set on those assets. And for that, we are saying to the browser, you know what, browser, this asset will never expire. So you don't need to make a conditional request, ever.

Okay, makes sense? Another cache-control that we have today is a new pattern that for those of you with experience with service worker, you have been already implementing it that you need a file, you need a logo. Okay, if it's in the cache, here, you have the logo. So I'm serving the logo from the cache, okay, makes sense?

For that, that's simple. But also in the background as a completely separate thread and process, I will go to the server and download the logo again and save it in the cache. I'm not updating it for you, for this navigation, it's for the next one. Does it make sense?

That has a name, it's called stale-while-revalidate. And now it's also available on some browsers directly for the browser's cache. So you can express that for that image, you wanna use state-while-revalidate and with the time that you want that for, can be minutes, hours, days. So you want that behavior.

You always serve from the cache, but also you are updating that in the background for the next time I need it. It's just a cache policy over the browser, okay? Now, I'm going to mention something that was asked on the chat, warming up the engines. Sometimes it's a good idea to help the browser to start as soon as possible everything.

But as we mentioned before, if everything is important, nothing is important. So I don't wanna preload everything. But maybe, maybe I can do some things that can warm up some engines. Let's look into our app, into Frontend Museum, and let me show you something. Let me do a clean reload.

So I'm going to disable cache. That means that every time you reload, it's a start from a scratch. Let me see if we can find this, what I want to show you is that we do have fonts.googleapis that is coming from a different domain, fonts.googleapis.com, right? So I have my website is localhost, that's one host, and Google font is coming from another file.

So another server, and the same happens if you're using CDNs or if you're using Google Analytics, or you are including a chat from a chat provider. So you're including scripts, files, resources from third-party domains. But you don't wanna preload all of them because, again, we cannot preload everything.

But something that we can do is we can warm up the engine to help with the DNS query and with the TCP and TLS connection. So, okay, don't download the file, but at least go and grab the DNS query, the IP address from that other domain before you know that you will need it.

Or go and open the TCP connection and start the SSL private key, public key negotiation. And for that, we can use dns-prefetch that it looks similar to preload, but in this case, it's not preloading a file, it's just getting the DNS. We are letting the browser know that it will need to know the IP address of that domain.

Also, we can preconnect, in this case, we're asking the browser, hey, why don't you go and start opening the connection? Because I know that you will need something from there. The browser doesn't know what to download yet, what to request over that connection, but it will start making the call.

Does it make sense? So that's why you can start doing that with a link element also as an HTTP response, and we can use this with early hints. Remember early hints? While the server is working, we already sent some hints earlier to the browser. Well, we can send, hey, open a connection to that.

Start the DNS with that while I'm working on the server for giving you the HTML. So in our case, in our project, something that we can do is with the only external file that we have is fonts.googleapis, also fonts.gstatic.com. So we can add the link rel, and it can be dns-prefetch or preconnect.

It's up to you, what do you wanna do? And you just preconnect to that domain. In fact, in a modern Google Fonts, you will get that by default. Two, three years ago, it wasn't available. Google Fonts, I'm using the font Inter. So you go to Google Fonts. You search for that font Inter, this one.

Here it says how to copy and paste the code. And you will see, let me copy that now. If you paste the one you have, it's already preconnecting to both domain. Can you see that, those two preconnects? But if you were copying the code a few years ago and you still have your website up and running, you don't have those preconnects.

So now Google is suggesting me to add the preconnect to both domains. Does it make sense? Not preload, preconnect.
>> So how does this differ from preload?
>> That preload will also go and fetch the file.
>> So why would you not just do preload instead of preconnect?

>> You can, the problem is that sometimes you have a lot of third-party domains. And maybe some of those domains are not so important for competing on the preload stuff. Because preconnecting and DNS prefetching is not competing with preload because it's not competing with the priority list or with the discovery list.

It's just something on the network layer. It's opening some things, and so you can do that in parallel without affecting the discovery queue and the priorities that you are downloading. Does it make sense? So it's like a different process.
>> Yeah, it's sort of like-
>> But if you need something to be preloaded, then you don't need to preconnect or DNS prefetch, because preload will do all the stuff as well.

>> Do it anyway, but if you preconnect to the URL, and then you preload one image, the preload is fine, but then it might mean that.
>> In fact, maybe you're right. In our case, I shouldn't be doing this for gstatic.com because we are already preloading a resource from it.

So I guess I should keep fonts.googleapis.
>> But if you did, if you were loading from gstatic.com, something else that you didn't preload, that would also load a little quicker because-
>> Yeah, because the connection is already there. And the connection is not lost immediately after one, because in HTTP/2, the connection keeps connected for a while to see if you're still downloading more stuff.

So it will wait one, two, three seconds before actually cutting the connection.
>> Yeah, you sort of have to know what you're doing.
>> Yeah.
>> While using-
>> But if you don't know what you're doing, at least you know where to look for it, and that's the browser, the DevTools, the waterfall chart.

You can use webpage test to analyze what's going on. And then you know, maybe this is because, the thing is that sometimes you don't assume. Sometimes it's better to go test this, see it on a waterfall chart and see what's going on.
>> Yeah, cuz weird things could be going on specific to your site.

>> Yeah, exactly.
>> In this particular example, do you need to do a preconnect to a domain when the next line is accessing the resource on that domain?
>> No, in that case, as I said, for this particular example, because I already have, well, let's say if the next line is preload, the answer is no.

If the next line is this one, the stylesheet, the answer is yes, why? Because having the link, this has to do with discovery, right? So yeah, the browser will know that it has that file, but that doesn't mean that it will download that file now. Preconnect will say, hey, open the connection now, because when the browser will download the file will depend on the priority of that file.

In fact, I think that the answer, Google has an answer for you even without explaining you this. But they are giving you a suggestion of adding the preconnect even if the next line is downloading the file. So Google is saying, yeah, you need the preconnect because maybe the browser will download that CSS in 100 millisecond, in 150 millisecond, not now.

The browser will discover the file, but the browser is not downloading all the files immediately after discovering them. It can wait. Preconnect will start that, will warm up the engine immediately.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now