Web Storage APIs

Caching the App Shell Practice

Maximiliano Firtman

Maximiliano Firtman

Independent Consultant
Web Storage APIs

Check out a free preview of the full Web Storage APIs course

The "Caching the App Shell Practice" Lesson is part of the full, Web Storage APIs course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano demonstrates caching the application's shell to allow the app to run offline. Cross platform resources can also be stored using the service worker.


Transcript from the "Caching the App Shell Practice" Lesson

>> Is my app offline capable right now, what do you think? Can we try that? I can't try to to turn off my server, turned off my Wi-Fi, but also within application in Chrome, within application service workers, I have an offline simulator. I'm not sure if you knew that.

So I can click offline simulator. This update and reload probably, I don't need it. This update on reload will actually try to force a service worker reload, but anyway. So if I refresh now, I can see if my app works offline. And yeah, it's not, why? Because yeah, I have the images, I have the IndexedDB database, but I don't have In the assets of my app, what is known as the app shell.

The app shell is all the assets that I need to render the whole app, the HTML, the JavaScript file, the CSS file, the form files and everything I need. So let's try to do that. Can we do that? Yes. Where? Well, I could do that in the page load, or something like that, but a better place is the service worker.

The service worker has another event called install. By the way, we are not covering in this course service workers in details. Here at Frontend Masters you have in the library many courses that you can find. There is one from Kai system, another one for me, for myself on PWAs, in case you want to get more about service workers, the lifecycle and what happens.

So when the server worker installs, here I can actually go and try to let's move this function into an async function, because I'm going to open a cache. And I can call this app shell for Coffee Masters, I can open a cache. And what I need to do with that cache is I'm going to add all URLs.

So here I will pass an array of all the assets that I need. So which assets do I need, what's the first one, the most important one?
>> HTML file.
>> HTML, should I write index.html, what do you think? So, am I in the server or in the client?

The service worker runs in the client, right? Is the client seeing index.html anywhere? So if I'm going here, well let's go back to online, so let me turn off offline. So if I go to the network, do I see index.html here somewhere? Because I read, the document, but it doesn't say index html.

So this is a tricky one. So the answer is no. But we should cache, forward slash, or dot forward slash, the default document, but not the request index.html, because that's not what the browser sees, make sense? Well, then I need one by one all the resources like style, CSS, then all the scripts.

The forward slash at the beginning is not actually necessary. So scripts/API.js, Scripts/app.js, and so on. You have the list to copy and paste if you want, okay? Order.js in the companion website, you have it ready. OrderRouter.js. On images, I think we need at least the logo.svg. My images, at least that's mandatory, and how do I know if I'm missing someone?

I will tell you. Okay, so this is going to precache all these assets, right? It's going to precache all these assets when the service worker is installed, but I have a problem. My service worker is already installed, how can I solve the issue? While I'm developing my app, update and reload, so I've been really weird reinstall the service worker every time I refresh, but that's not the normal operation, okay?

So if I refresh again, how do I know if this is working? I can look into my cache storage, and I can see now I have another cache with all the files, okay? Now, what am I up work offline now? That's right, so I will mark this as offline, I will refresh, and it's kind of there, right?

So I'm seeing something, not an error, but it seems like something is missing, okay? So if I go to the console, typically you will find what's wrong, can you spot what's wrong, quickly?
>> All, all the remote files from the up shell, right?
>> But which one is the first one that is giving me all the [INAUDIBLE].

>> IDV library.
>> IDV library, my wrapper, I didn't cash my wrapper. Can I cache a wrapper that is not actually from my domain? Because if we look at the index.html, it's this one. Can I cache from cdn, js, delivr, blah, blah, blah? Yes, I can. My service worker can cache and serve cross-domain assets only for my PWA, not for other PWA, for my PWA.

So I need to also add that one. And now that I did this, and you were looking at HTML, probably you have realized that also we have, for example, some CSS coming from Google Fonts. From here, I have these fonts, Google, blah,blah,blah, that it seems like we need.

And there is another one for icons, that is using material icons, that's an open source library. So you find open HTML I have another one. By the way I'm not saying that I'm ready yet, but I am showing you how you can go one by one with your resources.

So let's try now. Again, I'm going back to the browser application service worker, I'm turning off offline, I'm turning on update and reload, I'm refreshing. I can check if I want in my cache storage if the cross platform resources are here they are, okay? So they will be served probably.

So now if I'm going to application service worker, and I swap these options, again, I refresh and kind of there. So It's kind of working, well, I'm not seeing the logo it seems there, and also the icons. Does anyone spot why? First I'm using icon PNG, I think I served icon SVG, so I should change that.

But also, what's the problem with fonts and web fonts? Have you ever used web fonts before? So you insert a CSS, but that CSS, this is the CSS from Google, that's the CSS file, we can actually see it. The CSS file points to other files, to the actual font file, their work file.

So I also need to cache those files. At this point someone will say, hey, is there any way to just say, check all the files you need? Well, you can cache on the file, that's one way. And if not, the other way is like a tool that you put with a web pack, or something that checks everything you have and makes a list.

On HTTP there is no other way to know all the assets that the website will need later. We don't know, right? So it's a manual list. So anyway, here we can take advantage of what we see in the console, and I think that there are two [INAUDIBLE] files we need, this one and this one.

So, That one, and the other one. Their solution is instead of using the CDM for fonts is to download all the files, and serve everything from your project, so you can have more control okay, of what's going on. And images logo PNG, that wasn't available for some reason, let me see why?

Your images and the icon, since like there is an image icons, icon PNG. Also there is requesting, Icons, icon PNG, and I think this is logo SVG, the one I'm using a non PNG, that's why wasn't there. So one more time, we swap these settings, refresh, and now we do that again, I'm going to offline refreshing and ooh what happened there?

It seems like we have an error. So, go to the console, it failed to fetch the service worker, see why? I will try again. They didn't reload, we have an error? No, I'm not saving a slash order. Because this is a single page application, I'm saying me not only forward slash.

Make sense? So be honest do I need to serve all my routes? Typically you can add that behavior in the service worker. So, I'm talking about this, in the fetch, okay? When you are here, you check the URL. If the URL is order, you know you need to return forward slash.

Okay? So then you respond with a fetch to forward slash, or you go to the cache and search for forward slash, not for order, okay? That's how you solve the problem. But anyway, in my case, let's try forward slash, and let's see, we are offline, we will refresh, and it works.

So now our app, it works. And I can install the app, I need to be online for that? If I install my app, my PWA, I now have a full screen app for Coffee Masters on my Mac, that look like this. And it appears in the Alt tab as Coffee Masters, and it works offline.

And it works on Android. It works on iOS as well, even if you're offline. So we used IndexedDB to store the menu, and also the order. And we use the cache storage to store all the assets from the app shell, and also to store the images, okay? And they're being served from the service worker.

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