 Service workers are at the core of progressive web app techniques for resource caching and push notifications. In this session, you'll learn what a service worker is and what it can do for your apps. A service worker is a client-side programmable proxy between your web app and the outside world. It gives you fine control over network requests. For example, you can control the caching behavior of requests for your site's HTML and treat them differently than requests for your site's images. Service workers also enable you to handle push messaging. Now, service workers are a type of web worker, an object that executes a script separately from the main browser thread. Service workers run independent of the application they are associated with and can receive messages when not active, either because your application is in the background or not open or the browser is closed. The primary uses for service workers are to act as a caching agent, to handle network requests, and to store content for offline use, and secondly, to handle push messaging. The service worker becomes idle when not in use and restarts when it's next needed. Now, if there is information that you need to persist and reuse across restarts, then service workers can work with index DB databases. Service workers are promise-based. Now, we cover this more in other materials, but at a high level, a promise is an object that uses a kind of placeholder for the eventual results of a deferred and possibly asynchronous computation. Service workers also depend on two APIs to work effectively. Fetch, a standard way to retrieve content from the network, and cache, a persistent content storage for application data. This cache is persistent and independent from the browser cache or network status. Now, because of the power of a service worker and to prevent man-in-the-middle attacks where third parties track the content of your user's communication with the server, service workers are only available on secure origins served through TLS using the HTTPS protocol. We'll test service workers using localhost, which is exempt from this policy. By the way, if you're hosting code on GitHub, you can use GitHub pages to serve content. They're provisioned with SSL by default. Services like Let's Encrypt allow you to procure SSL certificates for free to install on your server. Service worker enable applications to control network requests, cache those requests to improve performance, and to provide offline access to cached content. But this is just the tip of the iceberg. We will explore some things you can do with service workers and related APIs. Caching assets for your application will make the content load faster under a variety of network conditions. Two specific types of caching behavior, suitable for use, are available through service workers. The first type of caching is to pre-cache assets during installation. If you have assets, HTML, CSS, JavaScript, images, so on, and these are shared across your application, you can cache them when you first install the service worker, when your web app is first opened. This technique is at the core of application shell architecture. Now, note that using this technique does not preclude regular dynamic caching. You can combine the pre-cache with dynamic caching. The second type of caching is to provide a fallback for offline access. Using the Fetch API inside a service worker, we can fetch requests and then modify the response with content other than the object requested. Use this technique to provide alternative resources in case the requested resources are not available in cache and the network is unreachable. Service workers can also act as a base for advanced features. Service workers are designed to work as the starting point for features that make web applications work like native apps. And some of these features are channel messaging API, which allows web workers and service workers to communicate with each other and with the host application. Examples of this API include new content, notifications, and updates that require user interaction. The notifications API is a way to integrate push notifications from your application to the operating system's native notification system. The push API enables push services to send push messages to an application. Service can send messages at any time even when the application or the browser is not running. Push messages are delivered to a service worker which can use the information in the message to update local state or display a notification to the user. Background sync lets you defer actions until the user has stable connectivity and this is really useful for ensuring that whatever the user wants to send is actually sent. This API also allows service to push periodic updates to the app so the app can update when it's next online. Every service worker goes through three steps in its life cycle. Registration, installation, and activation. To install a service worker, you need to register it in your main JavaScript code. Registration tells the browser where your service worker is, where it's located, and to start installing it in the background. For example, you could include a script tag in your site's index.html file or whatever file you use as your application's entry point with code similar to the one shown here. This code starts by checking for browser support by attempting to find service worker as a property in the navigator object. The service worker is then registered with navigator.serviceworker.register which returns a promise that resolves when the service worker has been successfully registered. The scope of the service worker is then logged with registration.scope. You can attempt to register a service worker every time the page loads, and the browser will only complete the registration if the service worker is new or has been updated. The scope of the service worker determines from which path the service worker will intercept requests. The default scope is the path to the service worker file and extends to all directories below it. So, if the service worker script, for example, serviceworker.js is located in the root directory, the service worker will control requests from all files at this domain. You can also set an arbitrary scope by passing in an additional parameter when registering. In this example, we're setting the scope of the service worker to slash app which means the service worker will control requests from pages like slash app, slash app, slash lower, and slash app, slash lower, slash lower, directories like that, but not from pages like slash app or slash, which are higher. A service worker cannot have a scope above its own path. This is in your service worker file, serviceworker.js. Now, thinking about installation, once the browser registers a service worker, the install event can occur. This event will trigger if the browser considers the service worker to be new, either because this is the first service worker encountered for this page, or because there is a byte difference between the current service worker and the previously installed one. We can add an install event handler to perform actions during the install event. The install event is a good time to do stuff like caching the app shell or static assets using the cache API. If this is the first encounter with a service worker for this page, the service worker will install and if successful, transition to the activation stage upon success. Once activated, the service worker will control all pages that load within its scope and intercept corresponding network requests. However, the pages in your app that are open will not be under the service worker's scope since the service worker was not loaded when the page is opened. To put currently open pages under service worker control, you must reload the page or pages. Until then, requests from this page will bypass the service worker and operate just like they normally would. Service workers maintain control as long as there are pages open that are dependent on that specific version. This ensures that only one version of the service worker is running at any given time. If a new service worker is installed on a page with an existing service worker, the new service worker will not take over until the existing service worker is removed. Old service workers will become redundant and be deleted once all pages using it are closed. This will activate the new service worker and allow it to take over. Refreshing the page is not sufficient to transfer control to a new service worker because there won't be a time when the old service worker is not in use. The activation event is a good time to clean up stale data from existing caches for the application. Note that activation of a new service worker can be forced programmatically with self-dop skipped waiting. Service workers are event-driven. Installation and activation events fire off corresponding events to which the service worker can respond. The install event is when you should prepare your service worker for use, for example, by creating a cache and adding assets to it. The activate event is a good time to clean up old caches and anything else associated with a previous version of your service worker. The service worker can receive information from other scripts through message events. There are also functional events such as fetch, push, and sync that the service worker can respond to. To examine service workers, navigate to the service worker section in your browser's developer tools. Different browsers put the tools in different places. Check debo-inging service workers in browsers for instructions for Chrome, Firefox, and Opera. A fetch event is fired every time a resource is requested. In this example, we listen for the fetch event and instead of going to the network, return the requested resource from the cache, assuming it is there. Service workers can use background sync. Here, we start by registering the service worker and once the service worker is ready, we'd register a sync event with the tag foo. The service worker can listen for sync events. This example listens for the sync event tagged foo in the previous slide. Do something should return a promise indicating the success or failure of whatever it's trying to do. If it fulfills, the sync is complete. If it fails, another sync will be scheduled to retry. Retry syncs also wait for connectivity and employ an exponential back-off. The service worker can listen for push events. Push events are initiated by your back-end service through a browser's push service. This example shows up notification when the push event is received. The options object is used to customize the notification. The notification could contain the data that was pushed from the service. Service workers can be tested and debugged in the supporting browser's developer tools. The screenshot here shows the Chrome DevTools application panel. There are lots of great resources to help you get started and find out more. Access them from the materials that accompany this video. In the lab materials that accompany this video, you can practice working with service workers and learn more about intercepting network requests.