Check out a free preview of the full JavaScript Performance course

The "Caching" Lesson is part of the full, JavaScript Performance course featured in this preview video. Here's what you'd learn in this lesson:

The browser will not ask for assets that it believes it already has recent versions of. Caching headers can be set in HTTP responses that let the browser know what it should and should not cache.


Transcript from the "Caching" Lesson

>> Steve Kinney: So the other problem, or the other solution, to this is when we need to send something, yes, have the browser go get it. But if we can have the browser not ask us for stuff, and just use the stuff it already has, that's gonna be faster, right?

And so a way to do that is to make use of HTTP caching. So imagine for a second that the year is 1997. We received a lot of great gifts that year. We received Puff Daddy and the Family's No Way Out. We also received Cache-Control response headers in HTTP/1.1.

Arguably one of those had more of an impact than the other. I'll leave it as an exercise to the viewer to figure out which one of those was more important in my childhood development. But yeah, we've got these Cache-Control response headers, that we put. You asked for something, we sent it to you, we have some headers that give you a little bit of extra information about it.

And caching is not gonna do everything. You send a post or a put, those are like, hey, change this data on the server. We don't cache those. But hey, you want this resource, you want this cat GIF, you want this JavaScript file? The CSS file? Like, if you already have it just use the one you have, don't ask me for another one.

Cuz I gotta get the thing half way around the world. This pipe is only so big, it's leaking, it's problematic. So these HTTP methods can be cached, Get, Options, and Head. A bunch of other ones that change stuff on the server, you wouldn't want them cached, right, like you wouldn't want them updating.

Something like cache, you want that to go to the server, so kinda makes sense. And there's a bunch of difference settings. We're not gonna talk too much about immutable, because I believe right now it's only supported in Firefox, not the rest of the browsers, but we will talk about these first four.

So imagine with browser cache that we're in one of three conditions at any given point. We don't have it in cache, that's easy. If you don't have it in cache, go to the server and get it, right, that makes sense. Stale, which is check but let's see if you have.

You have something in cache but it's out of date. Right, you need the new one. And valid which is you have this in cache. It's the right one. Don't talk to the network. Just use the one you have. And we all know that not talking to a server is going to be faster than talking to a server.

We understand the golden rules, right? Like skipping the entire, let me ask the server. Let me get these TCP packets. All that stuff over and over and over again. It is going to be faster to not do that. In a very simple express server you could tweak each one of these, from no-store to cache missing or no-store to no-cache to max-age, and so on and so forth.

Try each of these out. No-store which is like don't store. It's exactly what you think it is, right? Like browser, go get a new version every time. This could be, you might want this for your HTML page, right? Especially if it's a client setup that's just pointing at some bundles.

No, I need you to see what the new version of this one is. I updated this. Please go get the HTML page. No-cache means you can store a copy, but at least check with me to see if you have the most recent version. It will do what we call a conditional get, hey, have this version, is this the right version?

Right, there's a cost to that, because you still need to check. But if the server goes yeah, that's the right version, then it doesn't need to send you that file. And the other one is max-age, which you say like, listen, this file I just sent you, for the next however many seconds it's valid, just trust it, right.

Don't ask me, like maybe in a ten minutes you can ask me again, a year, whatever. We can do any of those things because caching is great unless it messes up, right? We can say, cache this for a long time, and then we ship some bad JavaScript file.

We wanna have some kind ofway of busting the cache. Because otherwise we can say, browser, hold on to this broken JavaScript file and never ask me for another one. That's called no longer a customer [LAUGH] right? That's called a user who has given up on you. That's not great.

And the user would have to do what we call a hard refresh, which is a little bit different in every browser. But it's not a refresh. It involves holding shift or hitting some other cocktail of keys to clear out the cache and do stuff. And you know who's gonna do that?

None of your users. None of your users are gonna be, you know what? I've probably got some bunk cache assets. What if I do a hard refresh? [LAUGH] No one's going to do that. I'm not even going to do that, right? That is never a thought, when something has not worked, that has ever crossed my mind.

I just go, like, there's something else that can give me a dopamine hit to go look at. I'm gonna go do that instead. So one solution for this is what we call Content-Addressable Storage, which is a very fancy way of adding a bunch of garbage to the end of our file name, right?

What this does is effectively rebuild it, we check some of the file, we give it a unique identifier, and we say, go get that file, and if we build a new version of our application, what has a new number? Right, you can tell the browser if somebody asks you for main.567ee7aa72b3ee48649.js, hold onto that for a year, right.

We can put that on our index study SMIL file and if we update our app, we updated the index study SMIL file, we'd be like, okay here's the new version. So we effectively get cache-busting for free with that. There's some interesting things you can do with CDNs, as well, right?

Because the CDN will also cache stuff, which is normally, if a CDN, the way that it works is you put your cool file on the internet, in the Cloud. That's either on your server, or in an S3 bucket, or whatever. The user goes to the CDN, and hey CDN, do you have name.567eea.

I can't, my memory's not that good. And it will either have it or it won't have it. If it doesn't have it, it will go to your server and get it, and then it will keep a copy of that in that region of the world, so the next person asks for it, they get the fast version.

So we can tell the CDN, hey, hold on to this and give it a max-age and it will do that. The browser can then hold on to it, so the browser won't ask. If the browser has to ask, it will go ask the CDN which hopefully has a version.

We don't wanna use this to hold on to everything forever because if we send them a bad version we're kind of up the creek. But, this s-maxage is for CDNs only because if we ship the CDN a bad version, we could reach out to that CDN and be like, yo, lose that version, clear it from your caches.

So it's another way to have a different max-age from what you set on the CDN. People only have to go as far as the CDN versus what they keep in their browser, right. And getting these right is a little bit of a fine art. Generally speaking, if you use web pack or a lot of the other build tools, the file naming part is done for you.

Right, it'll usually use that main and that string afterwards. Right, and that is, generally speaking, with barring some cool new future technologies, a great way of handling it. If the file changes, it will have a different file name. So you can store, you can set the max-age on the server, for that very long file name to a year.

That is the maximum you can do. Listen if you are like still asking for this file, right, cuz that's unique to that version of the file. Just use the one you have, right? And that is kind of the first step in fixing your load performances, making sure you have cache headers set.

Hold onto this, right? And don't ask me for it again. Now, for us as frontend engineers, it's always up in the air, and whether or not we control that, wherever I don't control those things, like the ops department controls all of them. I ask them, it is done.

Hopefully, or it's not done, or something along those lines, right? But the frontend engineer we don't always have control of those things. But there are other things that we do have control over, that I'm gonna kinda spend a little bit more time on, versus like those steps. So yep, we can reiterate I said before we ship because there is a bad version, we don't really have a great choice.

We ship the CDN a bad version, we can't talk to the CDN. We can't however, reach into all the browsers of everyone who has ever accessed our websites as we push out the bad version. It'd be like, yo, browser, clear that out. That's not how the web works.

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