PWA Tutorial for Beginners #17 - Cache Versioning
Skills:
HTML & CSS60%
Key Takeaways
Implements cache versioning in a Progressive Web App using service workers
Full Transcript
okay then my friends so now we are cashing all these different static resources right here when our service worker gets installed or here and then in the future when we're offline or have little connection or even just making Flex requests when we're online we're intercepting those we're seeing if that request is stored in our cache and if it is we're returning that to the user so that's good and now we've enabled kind of like an offline mode as well for our app so we're moving along but there is a problem with this now then what I'm going to do first of all to demo this problem is just come up here make sure you have updates on reload unchecked because I don't want this to interfere with what we're about to do and if you were a user viewing this website you're not going to have this checked and you're not going to have any kind of option check like this on a mobile app either so uncheck that now what I'd like to do is go to index dot HTML and in this recipes section all I'm going to do is add in an h6 we're going to change this file basically I'll keep this a class of center to essentially align it and give this a title called recipes so now we're changing our index dot HTML file and if I come over here and then refresh hmm I do not see that change so what's happening well don't forget we're intercepting all of the different fetch requests right here and when we reloaded the page is sent out fetch requests for all the different assets we needed including index dot HTML and that index dot HTML is in our cache and we're returning it right here now when we actually cache that it had the old content this wasn't here so what we're doing is now returning the old file that's in the cache because we've not recast this yet since we've changed it and the reason we've not recast it yet is because we're caching assets inside the install event and remember the install event only fires when the serviceworker has changed so if we change any of these assets over here that we want to cache then to recache then what we need to do is then change this file so that the install event refires now the best way to do this is by changing the name of the class right here and we can do it by just adding something like - V and then we'll just call it v1 for now and we'll version this so we'll have v1 v2 v3 every time we make a change to our files we can change this version and this is changing the serviceworker file so when I save it now and load it in the browser it's gonna re install that serviceworker over here and then because we reinstall it it's gonna fire all of this code which recache is all of the assets including the updated files that we have changed so let me save this now and come over here to the browser and notice that we have a new file now waiting to be active a new service worker and if we go to the console we can see we're caching the shell assets because we have that install event again it's wreaking all of those shell assets now we don't see those in the page yet because the new serviceworker was installed but it's not yet active and because it's not yet active it's not doing all of this stuff where we're getting the up-to-date thing from the cash from this cache of hit so if I save this now and go to application I'm gonna skip waiting and then we're going to refresh and now do you think this is going to work do you think that it's now going to get it from this new cache that we created site static v1 over here because now we have all of the updated files in here well let's give this a refresh and find out and no we don't we don't see the updated one so what's going on here well when we're intercepting these fetch requests even though we have the new serviceworker active when it's looking to match this request inside our caches it doesn't know which cache to lock in it could be v1 or this old one or v2 if we had one and it's gonna find the index file in each one so it might not know which one to return ok does that make sense so we might not always see the updated one here this isn't gonna work so what we need to do is address this problem when we update our static files we update version of our static cash name right here so that we're making a new cash and we're putting those updated files inside that new cash right and that's all fine but then what we want to do is actually delete the old cash because we don't need that anymore so then how are we going to delete the old cash version and where we're going to delete the old cash version well first of all we're we're going to do it in the activate event right here because at this point the new service work has been activated and the new service worker is going to be intercepting the fetch right here so what we need to do now is delete all of the old cash from here so how are we going to do that exactly well first of all I'm going to use event dot wait until again because again we want to extend the life of this activate event we don't want it to finish and then suddenly maybe stop the service worker because then whatever we're going to do inside it might not finish so we're going to use wait until and in there we pass some kind of action that's asynchronous that returns a promise now what we're going to do is as follows I'm going to say Cash's dot keys and let me just write this out first of all then I'll explain it and that returns a promise so I'm going to say dot then then we take the keys and fire a callback function and inside I'm going to console dot log the keys right here so then what I'm doing is saying cash is and then using a method called keys now this is an asynchronous method and it returns a promise and what this does is go to all of our caches and it looks for the keys and it gets those keys and takes them in into this callback function now what are the keys well we're logging them to the console right here so let me just save this come over here this shouldn't be in the console yet because we've not activated the new Service Worker so let's go to application service workers skip waiting and then refresh and if we go to the console now then we should see in a minute that we get the activate event oh no we didn't because we activated it over here so let me just do that again I'm just going to make a little comment here just make a change so we can reactivate it and now what I'm going to do is skip waiting over here which is going to fire the activate event and over here now we can see these different keys so these keys are the names of the two different caches we now have we can see those if we look inside the cache storage we see site static and site static v1 so what this method does this Keys method right here is returned towards an array of keys that we have and these are the two different cache names that we have now now what we want to do is delete any cache that is not this name because that means it's an old cache right so what we're going to do here is actually cycle through any caches we currently have in the browser and when we're cycling through those we're going to delete that cache if it's not this because in the future we might have three or four caches that we want to delete we're not just always deleting one cache we might have more so we need to cycle through them and check them if that cache key is not equal to this then we're going to delete that cache now this is actually going to take several attempts to do because if we have several caches then we're going to have to cycle through each one and for each one we're gonna have to delete each one okay does that make sense so what we need to do right here is say return and we're going to use promise dots all let me just write this then explain it now inside here we were going to take the keys and then we're going to use the filter method on this so I'm going to say dot filter like so and then I'm going to say inside key and we're going to be saying key not equal to static cache name and then I'm going to tack on a map method again don't worry I will explain this in a second again taking the key and this time I'm going to say caches dot delete okay so what are we doing here well remember wait until expect a promise passed into it now this returns a promise right but then inside of it we need to do several for an asynchronous tasks we need to delete several old caches and the minute were only going to be deleting one old cache but there could be several old caches in the future we want to delete and there will be in fact so what we actually need to do is wait for each of those asynchronous tasks to be done so if there's three caches we need to delete then we need to delete each one right and each of those delete for each cache is going to take some time to do each one is asynchronous and we essentially have a number of different promises returned to us but this expects one promise returned to us so what promise all does is taking an array of promises and then when each of those promises resolves then this is going to resolve as well I hope that makes sense so we're going to pass in an array of promises - promise - all right here right and this array is going to be first of all the keys which is just an array of the different keys of our caches we have two in there at the minute and what we're doing is filtering that array and we're seeing inside here look does the key of that cache so that thing that we have over here let me just see if it's still in the console does this site static equal to this thing up here right so if it's not equal if the key is not equal to the static cache name right here this statement is going to return true and if it returns true then it keeps it in the new filtered array so if the names are not equal it stays in the array and that makes sense because we want everything that we want to delete to stay in the array if these things are equal so if the key is equal to the static cache name that we have in the constant up at the top then we actually want to remove it from the array we filtering out of the array because we don't want to go to the next part with that and then delete that that is the thing that we want to keep as our cache so then once we have the leftover array of things that we want to delete what we're doing is mapping that array to an array of promises because remember promised to all expects us to pass in an array of promises so we're taking each key in the new filtered array and for each one we're saying Cash's dot delete and we need to pass in the key right here so this delete method takes this cash that we pass in the key which is going to be one of these things right here and it deletes that cash this is a promise it returns a promise is asynchronous so now we're returning a new array of promises right and then when each one of those promises are resolved this is resolved which were then returning which is a single promise and that's what this expects right here a single promise to be resolved so now we're successfully deleting all of the old cashes this probably seems very complicated at first but just run through this code again and see exactly what it's doing when it's activated we're getting the keys of all the caches we're taking those keys and firing a callback function then we're using promise to all and we're taking in those keys we're filtering this array of keys so that any key which is not equal to the static cash name up here remains in the array because they're the keys or the caches that we want to delete so we have a new array right here of caches we want to delete then we're mapping through that array and mapping it to a new array because this expects an array of promises so we're mapping through that array and we're taking the key in each position in that array of the cache that we want to delete we're deleting that cache using the key and this returns a promise right here so we're returning a promise for each position in this new array of caches that we want to delete this array of promises are all going to get resolved when they're all resolved promised to all resolves and then we're finished with the wait until a really hope that makes sense so now let me save this what I'm going to do is come over to the browser and if we go to application I'm going to go to skip waiting like so now you can see the old cache this over here it deleted it cycled through it and because that cache name was not equal to the new static cache name up here it deleted it it worked so now if I try to refresh then we to see the updated page now it knows to get that new cached asset from this cache right here and we get that new updated page and now every time we do this if I go to index dot HTML again and just going to change the title to ninja recipes and save it and what I'm going to do is go over to the service worker now we need to update this again so I'll say v2 because we changed our site static assets that were caching right here I'm going to save that then over here we can see if I go to the applications service workers I'm going to skip waiting to activate the new Service Worker then I can refresh and get the new cache asset and we see now site static v2 over here and we deleted the old one again ok so I hope that all makes sense this has probably been the most complex video so far but once you get your head around this code and why we're deleting the old cache it's all going to fall into place
Original Description
Hey gang, in this PWA tutorial I'll explain how we can start to version our cache, so that our cached assets are kept up to date and fresh.
----------------------------------------
🐱💻 🐱💻 Course Links:
+ Course files - https://github.com/iamshaunjp/pwa-tutorial
+ Modern JavaScript Tutorial - https://www.thenetninja.co.uk/udemy/modern-javascript
🐱💻 🐱💻 Other Related Courses:
+ Firebase Firestore Playlist - https://www.youtube.com/watch?v=4d-gIPGzmK4&list=PL4cUxeGkcC9itfjle0ji1xOZ2cjRGY_WB
Firebase Authentication Tutorial - https://www.youtube.com/watch?v=aN1LnNq4z54&list=PL4cUxeGkcC9jUPIes_B8vRjn1_GaplOPQ
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Net Ninja · Net Ninja · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Regular Expressions (RegEx) Tutorial #14 - Matching a Username
Net Ninja
Regular Expressions (RegEx) Tutorial #15 - Email RegEx Pattern
Net Ninja
Regular Expressions (RegEx) Tutorial #16 - Finishing Touches
Net Ninja
GraphQL Tutorial #1 - Introduction to GraphQL
Net Ninja
GraphQL Tutorial #2 - A Birdseye View of GraphQL
Net Ninja
GraphQL Tutorial #3 - Project (stack) Overview
Net Ninja
GraphQL Tutorial #4 - Making Queries (front-end preview)
Net Ninja
GraphQL Tutorial #5 - Express App Setup
Net Ninja
GraphQL Tutorial #6 - Setting up GraphQL
Net Ninja
GraphQL Tutorial #7 - GraphQL Schema
Net Ninja
GraphQL Tutorial #8 - Root Query
Net Ninja
GraphQL Tutorial #9 - The Resolve Function
Net Ninja
GraphQL Tutorial #10 - Testing Queries in Graphiql
Net Ninja
GraphQL Tutorial #11 - GraphQL ID Type
Net Ninja
GraphQL Tutorial #12 - Author Type
Net Ninja
GraphQL Tutorial #13 - Type Relations
Net Ninja
GraphQL Tutorial #14 - GraphQL Lists
Net Ninja
GraphQL Tutorial #15 - More on Root Queries
Net Ninja
GraphQL Tutorial #16 - Connecting to mLab
Net Ninja
GraphQL Tutorial #17 - Mongoose Models
Net Ninja
GraphQL Tutorial #18 - Mutations
Net Ninja
GraphQL Tutorial #19 - More on Mutations
Net Ninja
GraphQL Tutorial #20 - Updating the Resolve Functions
Net Ninja
GraphQL Tutorial #21 - GraphQL NonNull
Net Ninja
GraphQL Tutorial #22 - Adding a Front-end
Net Ninja
GraphQL Tutorial #23 - Create React App
Net Ninja
GraphQL Tutorial #24 - Book List Component
Net Ninja
GraphQL Tutorial #25 - Apollo Client Setup
Net Ninja
GraphQL Tutorial #26 - Making Queries from React
Net Ninja
GraphQL Tutorial #27 - Rendering Data in a Component
Net Ninja
GraphQL Tutorial #28 - Add Book Component
Net Ninja
GraphQL Tutorial #29 - External Query File
Net Ninja
GraphQL Tutorial #30 - Updating Component State
Net Ninja
GraphQL Tutorial #31 - Composing Queries
Net Ninja
GraphQL Tutorial #32 - query variables
Net Ninja
GraphQL Tutorial #33 - Re-fetching Queries
Net Ninja
GraphQL Tutorial #34 - Book Details Component
Net Ninja
GraphQL Tutorial #36 - Styling the App
Net Ninja
GraphQL Tutorial #35 - Making a Single Query
Net Ninja
Build Apps with Vue & Firebase - Udemy Course
Net Ninja
Updated Vue & Firebase Course (Udemy)
Net Ninja
Vue & Firebase Real-time Chat (Preview) #1 - Intro
Net Ninja
Vue & Firebase Real-time Chat (Preview) #2 - Project Structure
Net Ninja
Vue & Firebase Real-time Chat (Preview) #3 - Firestore Setup
Net Ninja
Vue & Firebase Real-time Chat (Preview) #4 - Welcome Screen
Net Ninja
Vue & Firebase Real-time Chat (Preview) #5 - Props in Routes
Net Ninja
Vue & Firebase Real-time Chat (Preview) #6 - Route Guards
Net Ninja
Vue & Firebase Real-time Chat (Preview) #7 - Chat Window
Net Ninja
Vue & Firebase Real-time Chat (Preview) #8 - New Message Component
Net Ninja
Object Oriented JavaScript Tutorial #1 - Introduction
Net Ninja
Object Oriented JavaScript Tutorial #2 - Object Literals
Net Ninja
Object Oriented JavaScript Tutorial #3 - Updating Properties
Net Ninja
Object Oriented JavaScript Tutorial #4 - Classes
Net Ninja
Object Oriented JavaScript Tutorial #5 - Class Constructors
Net Ninja
Object Oriented JavaScript Tutorial #6 - Class Methods
Net Ninja
Object Oriented JavaScript Tutorial #7 - Method Chaining
Net Ninja
Object Oriented JavaScript Tutorial #8 - Class Inheritance
Net Ninja
Object Oriented JavaScript Tutorial #9 - Constructors (under the hood)
Net Ninja
Object Oriented JavaScript Tutorial #10 - Prototype
Net Ninja
Object Oriented JavaScript Tutorial #11 - Prototype Inheritance
Net Ninja
More on: HTML & CSS
View skill →Related Reads
📰
📰
📰
📰
Angular vs React: Key Differences, Pros & Cons Compared
Dev.to · Elsie Rainee
Next.js Web App Development: Complete Guide for Fast, Scalable Applications (2026)
Dev.to · Avanexa Technologies
Next.js Quietly Fixed the Prefetch Problem Nobody Wanted to Talk About
Medium · JavaScript
A Fast Request, a Fast Parse and a Slow Page
Medium · JavaScript
🎓
Tutor Explanation
DeepCamp AI