Check out a free preview of the full PWAs: You Might Not Need That App Store course
The "Serving & Caching Resources" Lesson is part of the full, PWAs: You Might Not Need That App Store course featured in this preview video. Here's what you'd learn in this lesson:
Maximiliano introduces the three most common cache serving strategies: cache first, network first, and stale or revalidate. He demonstrates how to implement the cache first strategy by using the cache API to store assets in the cache and then serving them from the cache if they are available, or fetching them from the network if they are not.
Transcript from the "Serving & Caching Resources" Lesson
[00:00:00]
>> Maximiliano Firtman: Let's go over the three most common cache serving strategies. So let's say you downloaded all the files. Now you're ready to serve those files, and we will do that in our code. In fact, let's do that directly so we can actually see this work. So you can use self or globalThis remember is the same.
[00:00:23]
So I can add an event listener and do something when this service worker is installed, okay? So here I can go and talk to the cache API. The cache API work like this, it's caches.open with a name. So this is my PWA, it's a folder name within your cache.
[00:00:48]
This is promise-based, so we can use async/await, if you're used to that or just then, we receive the cache object and then we can, add URLs. So I can pass an array of URLs that I can create here. I can pass an array of URLs, URL that I wanna cache.
[00:01:15]
So what are the files that I need to render my web app offline? Index.html.
>> Maximiliano Firtman: App.js, styles.css, I'm not saying this is completely okay, okay, but
>> Maximiliano Firtman: Do you understand what I'm doing? So I'm just saying, hey, when the service worker is installed, I want you to open a new cache.
[00:01:39]
Actually, it's open or create, so if it's not created it will create one at that moment. Open pwa and when you when it's open to that cache add yours. I can use async await also here.
>> Maximiliano Firtman: And this is going to go and grab these three resources and store them in the cache that's the goal, I'm storing the assets, caching the assets.
[00:02:05]
This is known as pre-fetching the assets.
>> Speaker 2: You wouldn't add the web manifest file though?
>> Maximiliano Firtman: That's a good question, should I add the web manifest file? I don't need to because my web app is not using it. If the browser needed, the browser will have its own cache.
[00:02:26]
The same happened with the service worker itself, so the browser will cache it in a different place. I mean, if I can add it, but yeah, I'm not sure I need it. Okay, if I try to-, well, first let me remove this because if not I will never see anything, okay?
[00:02:44]
So let me comment that fetch event handler. By the way, if I refresh, will it be gone? The problem? But if I refresh I still see, hey, he, he, he. Because I need to wait for the new service worker to appear, so let's keep waiting. Refresh, and now I'm getting 404, which is correct, because I'm not in the route, okay, and now I'm back.
[00:03:09]
Now, didn't install the assets, how do I know? For that, in the application tab, we go to the Storage section and we look for Cache storage. I open Cache storage and I do have my PWA folder, when I go there I have the three files. So now my assets are installed client side.
[00:03:35]
It's as easy as this, okay? You just install the files. So, what happens now if I go and go offline? I already have the files, so when I reload when I'm offline, I'm still seeing the offline message, why is that? Because I'm cashing the files, but I'm not serving the files.
[00:04:03]
The service worker is not doing anything automatically. Okay you have a file, it's your problem, I don't know why you need that file, it's not my problem, okay. I cache them to the service worker is a very low level API. So we need to serve now, that's the last step, we need to serve the files.
[00:04:25]
To serve in the files now we can cover that. There are infinite strategies, but there are three that are the most important one, most used one. Cache first, network first, stale while revalidate. So let's go one by one, then we can use one or the other. What is this, let's talk about cache first.
[00:04:46]
I mean the name give us a hint about the idea. But this is the structure so you have your PWA one, the PWA needs a file, okay, a CSS. So it makes a request, the service worker is drop in the request and say wait, wait, wait, wait, I don't want you to go to the network.
[00:05:05]
Let's first check, let's search in the cache, if I have the file that you are requesting or not. If I have the file, it is known as a cache hit. I'm responding with the cache response, okay? So what you're expecting? It's in the cache, okay, grab it here you have it from the cache.
[00:05:26]
But maybe it's not in the cache, because maybe I don't have that file that JavaScript is requesting or CSS is requesting, in that case, it's a cache miss. So I forward the request to the network, and then the response will go back to the PWA. So it's called cache first, because cache has priority.
[00:05:47]
If it's in the cache, I use the cache version, if it's not in the cache, I go to the network, does it make sense? Do you understand the idea, the process? What's the advantage of this performance? Because if I have it in the cache is always faster than the network.
[00:06:05]
The network has latency, I mean, looking into a local database also has a latency, but the difference is probably around 500x, 1 milliseconds versus 500 milliseconds, if you're lucky. Okay, so that's why it's better to use the cache. The problem with that had to do with updating the content, because I always have an old version maybe.
[00:06:30]
I'm not going to a server, so I don't know if it has changed in the server, make sense? Yeah, so if you wanna implement this, I can write it from scratch because I've done it so many times that I know the code, but I don't wanna spend too much time with this.
[00:06:45]
We are not focusing on service workers in this workshop. I have a snippet here ready to copy and paste. So if you go to snippets.txt, we already done the installation part, so we don't need to do that. Here I have the cache first strategy, so I will just copy that one and then explain it, it's not a big deal.
[00:07:03]
But anyway, it's already commented, so it's simple to read. Remember the event respondwith I used before for responding with a fake answer? Well, instead of doing that, I'm responding with a promise. Caches.match, will search in the cache, and then it can give me a response, or it can be undefined, if it finds the response or not.
[00:07:27]
So if I do have a response, I'm returning with that response, returning to who, to respondwith. So if it's a cache hit, I'm giving that response from the cache to respondwith. If it's not in the cache, I'm returning a fetch to respondwith. I'm responding with a fetch, a fetch is a fetch API to go to the network.
[00:07:50]
This is kind of in the weeds, but I'm curious about line 14, you're passing the event.request object to it. But just off the top of your head, the .match method, that always takes a request object. A request, you can also pass a URL, actually. It accepts the strings, the URL, or a request object.
[00:08:11]
So actually, the cache storage is key-based, and the key is the HTTP request.
>> Maximiliano Firtman: The request option that includes a URL, but it can contain other properties like headers, okay? If you wanna get more into the cache storage, you can check the browser web storage course at Frontend Masters where we cover that API in details, okay, the storage API.
[00:08:40]
So yeah, there is a lot to learn in the web platform, right? So now, let me go back here, if I refresh, first, I need to make sure that the new code is in place, okay? So keep waiting, okay? So okay, I'm refreshing, I guess that everything is there, let's try offline, I click Offline.
[00:09:00]
Remember, this is simulator, I can also try to stop the server. If I refresh, cross your fingers, it's working, but I didn't mark offline, by the way. It's not working, you say, come on, what's going on? Let's go to the console, I'm getting an error fail to fetch.
[00:09:19]
But actually, line 21 is here. Yeah, actually, the problem that I received is that it failed to fetch. When you say, why did it want to fetch? Because that's for the network of course because I was offline, it couldn't fetch, why? Because I have a problem, actually, I already hinted that this code wasn't 100% right I have a problem here, let's see if someone realizes what's going on.
[00:09:55]
>> Speaker 3: So this is my question, is it matching strings on the URL?
>> Maximiliano Firtman: Yeah, it's matching a string with URLs.
>> Maximiliano Firtman: So the problem is that it's trying to go to an error. So it's not in the cache, so it's a cache miss. Why it's not finding the HTML?
[00:10:14]
Actually, the HTML is the one that is not there.
>> Maximiliano Firtman: Because it shouldn't be index.html, this is a pretty common error. Index.html is the name of the file, not the actual HTTP request that we make, does it make sense? The HTTP request is actually /.
>> Maximiliano Firtman: The URL, not the files on the server, that was wrong, okay?
[00:10:45]
So again, let's try again, should I refresh? Well, actually, I'm offline, so I need to go online, okay, refresh. Now I need to wait for the new service worker to be activated, okay. Now I refresh again, just in case, and then offline, refresh, and again, you'll say, is it done?
[00:11:06]
Well, let's check the local storage, I'm sorry the cache storage, the cache storage is empty. So there might be another problem here.
>> Maximiliano Firtman: Look for it offline, refresh, there we are. Okay, I'm service working, ready to serve. I'm going to Application > Cache storage > PWA, and now I'm getting what I want.
[00:11:31]
Okay, so the forward slash is cached that here it says it's text, HTML, I can click it, I can see the preview the things that my font is so big that I've not seen the preview, but I can see the preview there at the bottom. So let's try one more time, we go to service worker, we go offline.
[00:11:50]
I don't need upload on reload, it doesn't matter, because we're offline. If I refresh, well, now it's working. So, is it ready? Well, actually there is one more thing that I could do before saying it's ready, and its offline capable. Actually my HTML, it's also pointing to this library, I'm not caching the library, Does that make sense?
[00:12:18]
So also I should check in my CSS, If I have another file that I need, which file I need? This web font, if I don't cache that, maybe you say, but it worked. Yeah, because also there is another cache, the browser's cache that had that file. But maybe in a month, if I open the PWA, it has my files but not the font, does it make sense?
[00:12:42]
Because we have my cache and then we have the standard normal browser cache, so sometimes maybe that file was already in the standard cache. So I also need to add all the assets that you need, even if they are from other servers, does it make sense? Can I cache files that are not part of my service?
[00:13:03]
Yes, you can.
>> Maximiliano Firtman: Yes, you can, so I have that one and I also have this one. I think with that, we should be good.
>> Maximiliano Firtman: Does it make sense? So add all your assets, not just the assets from your server. Everything you need to render at least what you want offline.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops