 How do you pick a caching strategy and how does that work for a real website? I'm Sam Dutton and in this video I'll show you how to implement caching for a site that relies on user-generated content such as a blog or social site. Do you remember the PWA principles? Web experiences should be fast, integrated, reliable and engaging. So let's look at a real-world example. A social media app with user content such as an image feed. Static resources like our app shell can be pre-cached since we know what these resources are ahead of time and they're required for most of our app. The code shown here gives a name for our cache and an array of resources that we intend to cache. For an app shell, this could be index.html, core, CSS, logos, even core JavaScript and other assets. Next we use the cache API to cache all those app shell resources during the service worker's install event which is fired one time only when the service worker first executes. Caching during the install event ensures that the service worker will have access to all the files the app expects to use because if any of the files fails to cache, the add-all promise will reject and the service worker won't install. Just a quick aside here. To conserve resources, service workers terminate into an idle state when they aren't in use. Now because of this potential for termination, we wrap the cache API code in the wait until method. The wait until method ensures that our service worker doesn't preemptively terminate while waiting for the asynchronous caching logic. For dynamic resources like images, we could consider runtime caching, but for a social media app there are going to be way too many resources and the amount of files we'd have to cache will grow out of control. Now we could try to implement a caching strategy that limits the number of files, removing old or outdated ones, but that's quickly going to get complex and error prone. So let's try something else. Instead we can use Workbox, which we should probably be using for all of our service worker code anyways. Now Workbox is a fantastic library that abstracts common service worker use cases and covers edge cases that we might otherwise miss. We start by importing the library in our service worker from a CDN. Then we establish a route for all our image files. Next, we configure a cache-first strategy that will pull images from the cache before going to the network. Other strategies are also available and it really depends on your use case, what you choose. So we call this cache images. And finally, we can configure the cache to only hold 60 images, automatically removing old ones for new ones so that the cache never overfills. We can also set cached images to expire, in this case after 30 days. Now, what about something like favorited images or articles? For example, if clicking the heart icon saves user content offline. In this case, we'd want to implement a cache on interaction strategy. Here we have a listener for our posts, which will cache a post's image when the user clicks it. Alternatively, if we had a blog on news site and our content was articles, we could grab all the resources for a favorited article and cache them all. Now, assuming that our data comes from a JSON endpoint, we could just cache the JSON file response. We could implement whatever caching strategy was appropriate. In a store app, maybe that could be network-first, getting the most up-to-date prices by default, but still showing users old prices if they're offline. Now, this works okay for read-only data like prices and is probably the simplest solution, assuming, of course, that it's not a problem to show old prices. But what about data that changes? What about data that's edited by the user, such as in a social media app or messaging app? If we want to persist the data, we'd need to recache the JSON on every change. This could get really unwieldy for client-side changes. We'd need to create a JSON response manually to update the cached data file. And that's pretty tricky. We tried it, and it took a while to figure out what we were doing, and it got pretty buggy. A better option for dynamic data is to use client-side data storage. Indexed DB is a scalable, no SQL object store built into the browser. It allows you to store just about anything, not of any JavaScript data type, in the user's browser. In addition to the usual create, read, update, and delete actions, indexed DB also supports transactions and indexes. Because indexed DB is not relational, it doesn't support complex queries. However, responses are very fast. This code creates a messages object store in indexed DB. And in this code sample, you can see how we could add a user's posts to the object store. In this case, we opened the database we just created, offline BD, and beginner transaction. The transaction will occur on the posts object store and be a read-write transaction, meaning that we can both read and write in this case. Then we get access to the messages data store and add a new messages object to it. In this case, a message of, yay, happy from David. Once finished, we complete the transaction. So there you have it, the experimental user-generated content. Thanks for watching, and be sure to check out the other videos in this series that cover caching for other types of content.