 How can you handle caching for sites with server-generated content that changes frequently? New sites, for example. Well, remember the AppShell model. The idea is to cache the core resources required for most of your site. Let's look at a simple example. In response to a request for the home page, the server just returns an app div that will be populated with content on the client's side by the Render Stories script. The Render Stories script fetches content from another route in the example server or a third-party API, and then renders that content in the app div in the HTML shell. Loading will look like this. First, there'll be a delay for the initial HTML shell. The shell will appear with a loading symbol, such as a spinner, and make requests for content. Next, there'll be another delay while waiting for content, and then finally the content will arrive and fill out the shell. So let's add some service worker caching to our app. We won't show it here, but we start by adding a registration script to our shell. Our service worker precaches our core app files and implements a cache-first-fetch handler for these precached resources. Now the initial loading of the app will be the same as before, wait for the shell, then wait for the content. This time, however, the app shell is cached as well. So for future loads, there'll be no waiting for the initial HTML shell. Let's see what happens when we add some server-side rendering. In this example, instead of putting the loading spinner in our app div of the HTML shell page, we render content directly on the server. Now the initial load looks like this. First, there's a delay for initial HTML with server-side rendering, SSR, of content. The shell, well not really just a shell, appears fully populated with content. But the service worker is going to cache this rendered page, which leads to an issue. Future loads will be instant, but we'll load the previously cached and now outdated content. Now to fix this, we need to distinguish on our server between the shell and the fully server-side rendered content known as SSR. In this example, we're going to use a query parameter. For our sample app, we update the server to send the original non-SSR shell when we have the shell query and to send the fully SSR version otherwise. In our service worker, we're going to pre-cache the same assets, but this time we append the shell query string to our shell resource. This means rather than pre-caching the SSR content that the app receives on initial load, we pre-cache the forward slash question mark query, which should only return the app shell content, since we just updated our server to do just that. The actual pre-cache step looks the same as before. The only real difference is that the shell query was appended to our home page URL. So the forward slash question mark shell is pre-cached instead of the forward slash for our home page. Or in other words, the shell content is pre-cached instead of the fully server-side rendered page. The last step is to update the fetch listener. Here we check each request to see if it matches one of the shell URLs to cache, which in this case just represents our home page. If we find that the request is one of those shell resources, again, this is just the home page in this example, we append the shell query string to the request before we handle it with respondwith. Our respondwith call then works just like it did before, checking the cache for the resource first. Now when the home page loads, the service worker will fetch the empty shell from the cache instead of fetching an outdated server-side rendered page, which also isn't even cached in this case, thanks to our updated pre-caching logic. So the new first load behavior goes like this. First up, wait for the fully server-side rendered page and then show it. Now the difference is that now the app shell resources are pre-cached in the background, and this means that future loads work just how we wanted. No delay for the initial HTML shell, the shell appears with a loading symbol and requests content. And there's an inevitable delay waiting for content. We can't get around that, but we're assured of up-to-date content that arrives and fills out the shell. So that's it. Strategies to take advantage of app shell caching that can also work well with content rendered on the server. So thanks for watching. You might also want to have a look at the other videos in this series that cover caching for other types of content. There's also lots of useful information to help you get to grips with caching strategies in our lab exercises and in our workbooks.