 Service worker implementation can be quite complicated, especially with larger projects. There may be a number of files that need to be pre-cached and hundreds of requests for different types of assets that all need to be handled differently. Google maintains two tools that make it easier to work with Service Worker and the Cache API. These work really well together to give you a solid strategy for different types of caching, for different resources, in order to reduce network requests and make what you build work offline. In combination, they work really well with the AppShell architecture that we describe elsewhere. In a nutshell, we recommend you use SW Precache and SW Toolbox for your sites. Even if you want to roll your own implementation, SW Precache and SW Toolbox are a great place to start. SW Precache is a tool you add to your build process to generate a Service Worker file that will ensure that certain static resources are cached. These resources are likely to be the core AppShell architecture components, index.html, main.css, main.js, your company logo, and so on. It also gives you ways to implement different caching strategies for different resources. SW Toolbox mops up the rest. You add code to your Service Worker that describes what files you want to cache and the strategy you want to take. Precaching every resource that a site needs to work offline isn't feasible. Some resources are too big or aren't used often enough by all users to make Precaching feasible. Other resources are dynamic, such as the responses from a remote API or service. So let's see how to get started. SW Precache generates a production-ready Service Worker. You can specify resources for the Service Worker to cache on install. There are many other options for configuring the generated Service Worker to accomplish whatever you need. We cover these options here. Now, just a quick reminder, SW Precache is a node module used to generate Service Worker code to precache specific resources so they get cached and work offline. SW Precache can be used with JavaScript-based build systems like Gulp or from the command line. You can use the module directly or, if you'd prefer, use the wrappers around SW Precache for specific build environments, like Webpack, for example. It works really well with the SW Toolbox library, which works well when following the App Shell and Dynamic Content model. In a production system, we want our tools to handle building the Service Worker with SW Precache and add the Service Working Generation Task. In this example, we add SW Precache to our default Gulp Task, so it will run every time we do work in the application. In this section, we'll cover how to automate the process by adding a Generate Service Worker task to a Gulp workflow. Now, the first thing you need to do is to tell Gulp what plugins to use, because Gulp must know what plugins to use. We register each plugin to a variable by assigning a require statement for each of the plugins we use. In this case, we add path and SW Precache to the list of plugins at the top of the build file. We can then create an array of variables to reflect the paths used in our application. Now, right now, the code we only use has a source child to represent the root directory of the application. The Service Worker task takes the static elements we want to cache for our application shell. We tell the Gulp task what files we want to cache in the Static File Globs section, marked as 1, and what files to import in the Import Scripts section, which is marked as 2. The scripts imported will be used by SW Toolbox. Strip the root prefix, 3, to turn the element into a relative path. Now, if we do not strip the source prefix, we would be working with absolute paths. Absolute paths are written differently in Windows, C slash directory, and Macintosh Linux slash directory. Now, the Service Worker task takes the static elements we want to cache for our application shell. We tell the Gulp task what files we want to cache in the Static File Globs section, marked as 1, and what files to import in the Import Scripts section, marked as 2. The scripts imported will be used by SW Toolbox. Now, we can run Gulp to generate the Service Worker. SW Precache generates a production-ready Service Worker, and we can specify resources for the Service Worker to cache on install. There are many other options for configuring the generated Service Worker to accomplish whatever you need. We cover these options here. Just a reminder, SW Precache is a node module used to generate Service Worker code to precache specific resources so they work offline. SW Precache can be used with JavaScript-based build systems like Gulp or from the command line. So you can use the module directly, or if you'd prefer, use the wrappers around SW Precache for specific build environments like Webpack. Now, it works well with the SW Toolbox library, which works well itself when following the App Shell and Dynamic Content model. There may be times when you want to test the result of using SW Precache and don't want to have to change your build system for every version of the experiment. SW Precache allows you to use the tool from the command line. We will first create an SW Precache config.json file with our SW Precache configuration. In this example, static file globs indicates the path to each file we want to precache, or a glob to match multiple files in the case of images. And strip prefix tells SW Precache what part of each file to remove. Once the SW Precache configuration is ready, we run it with the following command. SW Precache config, path to SWprecache config.json verbose. You can get all that. You can use config to get the location of SW Precache config.json or add the verbose flag to provide additional information. SW Toolbox provides service worker tools for caching assets from runtime requests. SW Toolbox simplifies the creation and customization of caching rules and strategies. At its simplest, SW Toolbox creates one or more routes. Routes match request URL patterns and route them to the specified handler. We start each route with Toolbox.router. We can then specify an HTTP method to match. This can be get, post, put, delete, or head. The first argument after the HTTP method is the URL pattern. This can be written using express-like syntax or a regular expression. We'll talk more about that later. The second argument is the request handler. This can do anything we choose. In this case, we've used the built-in network-first strategy for requesting and caching resources. More on that later as well. There is an optional third parameter, the options objects, that lets us specify some options for the route. Now, most of these options give us more control over the cache for that route. The example defines a route using the get HTTP verb, matching the pattern slash app slash index dot HTML. And using a network-first handler, it will fetch the resource from the network first and fall back to the cache if the network is not available. SW Toolbox provides five handlers for responding to route requests. Toolbox dot network first. Try to fetch the resource from the network and store the response in the cache if successful. Otherwise, try to fetch resource from the cache. Now, this is the strategy to use for basic read-through caching. It's also good for API requests, where you always want the freshest data when it is available, but would rather have stale data than no data. Toolbox dot cache first. If the request matches a cache entry, respond with that. Otherwise, try to fetch the resource from the network. If the network requests succeeds, update the cache. Now, this option is good for resources that don't change or have some other update mechanism. Toolbox fastest. Request the resource from both the cache and the network in parallel. Respond with whichever returns first. Now, usually, this will be the cached version if there is one. And this strategy will always make a network request, though, even if the resource is cached. However, if or when the network request completes, the cache is updated so that future cache reads will be more up to date. Toolbox dot cache only. Resolve the request from the cache or fail. This option is good for when you need to guarantee that no network request will be made. For example, saving battery on mobile. Toolbox dot network only. Handle the request by trying to fetch the URL from the network. If the fetch fails, fail the request. Essentially, the same as not creating a route for the URL at all. We can use one of two pattern matching languages to write our URL patterns. These languages allow us to match wildcards in our patterns. They also let us match requests from different domains. But note, if you're matching a single same origin URL, a simple string will work. Now, if you're familiar with express.js, you can create routes with a syntax similar to its routing syntax. If the URL pattern is in string quotes, it is assumed you're using express style routing. To match requests from a different origin using express style routing, we must specify the origin in the origin parameter of the options object. In the first example, we will intercept all get requests to googleapis.com and use the cache first strategy. If the response is in the cache, we return it. If it isn't, we fetch it from the network and add it to the cache. The pattern in the second example intercepts all get requests ending in fly, like butterfly and dragonfly. For all the requests it matches, the route uses the cache first strategy. If you're more comfortable working with regular expressions, you can define them in routes. Pass a regx object as the first parameter of the route, and this regular expression will be matched against the full URL request and path to determine if the route applies to the request. This matching makes for easier cross origin routing since the origin and the path are matched at the same time without having to specify an origin separately like we did with express style routes. To use a regular expression in the URL pattern, do not wrap the URL in quotes. The route in example one will handle all requests that end with index.html, regardless of how deep into your application structure the route finds the match. Notice we have defined a custom handler for the request. The second example will handle all requests that begin with https.api.flickr.com using a network-first strategy. This will ensure that your app gets the freshest content possible, but will still get some content if you're offline. SWPrecache also gives us the ability to control the cache and its characteristics. We can define a cache parameter in the options object. In the example, the express route handles requests ending with googleapis.com using the cache-first strategy. In addition to handling the origin, we customize the cache itself. We give it a name, Google APIs. We give it a maximum size of 10 items indicated by the max entries parameter. We set the content to expire 86400 seconds, that's 24 hours, after we've started. And whenever there are more than 10 items in the cache, the oldest items will be purged to make room for the new. Content will also be expired after 24 hours, that's 86400 seconds. Now, to use SW Toolbox, you include the SW Toolbox module in your service worker along with a custom script containing the routes. In the lab materials that accompany this video, you can find out more about how to install and use SW Toolbox and SW Precache and how to incorporate them in your workflow.