1. What is ServiceWorker

    The Service worker is an event driver registered with a specified source and pathworker, it uses JavaScript to control associated pages or websites, intercepts and modifies access and resource requests, and cache resources in a fine-grained manner. You have complete control over how your application behaves in certain situations, most commonly when the network is unavailable.
  2. What is a worker?

    Create a Worker object using a constructor (for example,Worker()) that takes a URL of a JavaScript file that contains the code that will run in the Worker thread

    Using Web Workers, a Web application can run a scripted operation in a background thread independent of the main thread. This has the advantage of being able to perform time-consuming processing tasks in a separate thread, allowing the main thread (usually the UI thread) not to block/slow down as a result.Copy the code

    Features:

    (1) Same-origin restriction The script files assigned to Worker threads must be the same origin as the script files of the main thread. (under the same protocol and domain name) (2) DOM limits the global object where the Worker thread resides. Different from the main thread, DOM objects of the webpage where the main thread resides cannot be read, and objects such as Document, window and parent cannot be used. However, Worker threads can have navigator objects and Location objects. (3) correspondence Worker thread and the main thread is not in the same context (this environment the corresponding objects for DedicatedWorkerGlobalScope, Dedicated workers used by a single script. Shared workers use SharedWorkerGlobalScope. , they cannot communicate directly and must be done via messages. (For example) Most window object methods and properties are available in the Worker context, including WebSockets, and Data storage mechanisms such as IndexedDB and the unique Data Store API in FireFox OS. (4) The script restricts the Worker thread from executing the alert() and confirm() methods, but can use the XMLHttpRequest object to make AJAX requests. (5) file restriction Worker threads cannot read local files, that is, they cannot open the local file system (file://), and the scripts loaded by them must come from the network. Note: The ability to redirect network requests is very dangerous to expose to man-in-the-middle attacks. Therefore, for security reasons, Service Workers only support HTTPSCopy the code

    For more information see Functions and classes available to workers.

  3. The Worker and shareWorker

    WebWork can be divided into two types, Worker and shareWorker

    Dedicated Worker what’s the difference between them?

    • The most obvious difference is that shared workers can be shared while workers cannot. Reflected in the following convenience
      • Scripts from the same origin can all communicate by accessing the same shareWorker object, whereas worker objects can only be accessed by the scripts they create
      • Different scopes:
        • All shareWorker objects share the same scope
        • The scope of a Worker object is associated with the main process that created it.
    • Shared types must communicate via an open active port (this part is implicit in dedicated workers).
    / / show open myWorker. Port. AddEventListener ("message".function(event) {
                alert(event.data);
            }, false); myWorker.port.start(); // Open implicitly: use onMessage myworker.port.onMessage =function(event){
            alert(event.data);
        }
        
    Copy the code
  4. ShareWorker and ServiceWorker

    As mentioned above, a serviceWorker is also a worker. Therefore, he inherits all attributes and characteristics of Worker

    • ServiceWorker is the same as shareWorker
      • Runs in the global Workers context (with its own thread)
      • Not tied to a specific page
    • Unlike shareWorker:
      • SeriveWorker does not depend on any pages (shareWorker is closed when all referenced pages are closed)
      • Seriveworkers have a longer life cycle,
      • SeriveWorker has its own module update mechanism

    Specific differences :www.w3.org/TR/service-…

  5. For details on how to kill worker processes, error monitoring, etc., please refer to developer.mozilla.org/zh-CN/docs/…

  6. ServiceWorker

    ServiceWorker can be independent of any page, once registered it can persist (unless destroyed manually) and be used as a URL accessible to users in its domain.

    Sw allows your application to access local cached resources First, so it can still provide basic functionality (generally called Offline First) while Offline until it receives more data over the network.

    Features:

    1. ServiceWorker is also a worker, so it has Dom restrictions and cannot operate Dom directly. However, you can control the relevant page to manipulate the Dom by sending messages via postMessage
    2. The ServiceWorker Cache mechanism relies on the Cache API
    3. Serviceworkers are all programmed based on the Promise interface
    4. ServiceWorker relies on HTML5’s FETCH API for network programming
    5. ServiceWorker must run under HTTPS (for security)

    The life cycle

    The event

    How to go offline?

    ServiceWorker is a virtual proxy between the browser and the network. In its worker context, it is possible to listen for all sw-scoped resource request actions via the FETCH event and to hijack the HTTP response to customize the return via the Event.respondwith () method.

    The specific steps are as follows:

    registered

        if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('sw.js', { scope: '/' }).then(function(reg) {
            // registration worked
            console.log('Registration succeeded. Scope is ' + reg.scope);
        }).catch(function(error) {
            // registration failed
            console.log('Registration failed with ' + error);
        });
        }
    Copy the code

    Installation and activation: Populate the cache

    Note that cache. AddAll will fail if one path is not correct.

    // In sw.js this.adDeventListener ('install'.function(event) {
            event.waitUntil(
                caches.open('v1').then(function(cache) {
                return cache.addAll([
                    '/'.'/index.html'.'/style.css'.'/app.js'.'/image-list.js'.'/star-wars-logo.jpg'.'/gallery/'.'/gallery/bountyHunters.jpg'.'/gallery/myLittleVader.jpg'.'/gallery/snowTroopers.jpg']); })); });Copy the code

    Customize the request response

    For a request, we first look in the cache to see if the resource is cached. If it is, we return the cached resource. If it is not, we request data from the network instead and cache it so that the next time the same request occurs, we can use the cache directly. This strategy is cache first

        self.addEventListener('fetch'.function(event.respondwith (event.match (event.request).then(event.respondwith (event.match (event.request).respondwith (event.match (event.request).then())function// Caches. Match () always: // Butin case of success response will have value
                if(response ! == undefined) {return response;
                } else {
                return fetch(event.request).then(function (response) {
                    // response may be used only once
                    // we need to save clone to put one copy in cache
                    // and serve second one
                    let responseClone = response.clone();
                    
                    caches.open('v1').then(function (cache) {
                    cache.put(event.request, responseClone);
                    });
                    return response;
                }).catch(function () {
                    return caches.match('/gallery/myLittleVader.jpg'); }); }})); });Copy the code

    So we have an offline cache.

    Update, clean up

    1. How should we update the Service Worker when updating the cached version? The version number we store in the cache name is the key to this problem:

          let cacheName='v1'
      Copy the code

      When the version number is updated to V2, a new Service Worker is installed in the thread and the latest resources are cached in v2’s cache. The old service worker will continue to run correctly until no pages are using it, at which point the new service worker will be activated. Trigger the Activate event:

    2. Clear the cache

          self.addEventListener('activate'.function(event) {
              var cacheWhitelist = [cacheName];
              event.waitUntil(
                  caches.keys().then(function(keyList) {
                      return Promise.all(keyList.map(function(key) {// Remove caches that are not whitelistedif (cacheWhitelist.indexOf(key) === -1) {
                              returncaches.delete(key); }})); })); });Copy the code

    uninstall

    How to uninstall serviceWorker when our website application no longer needs it? Don’t register serviceWorker for the next version? Instead, we can use Unregister in the new version.

        if ('serviceWorker' in navigator) {
                navigator.serviceWorker.ready.then(registration => {
                registration.unregister();
            });
        }
    Copy the code

    Is that all? Note :registration.unregister() unloads sw, but does not remove our previous cache files, so before uninstalling SW we must eliminate IndexedDB,Storage, and Caches used in serviceWorker

    Caching strategies

    The following are the most conservative caching strategies.

    • HTM: If you want the page to be accessible offline, use NetworkFirst. If offline access is not required, use NetworkOnly. Other policies do not recommend using HTML.
    • CSS and JS: The situation is complicated, because the CSS and JS of general sites are in the CDN, and the SW has no way to determine whether the resources requested from the CDN are correct (HTTP 200). If the result of caching failure, the problem will be big. In this case, I suggest using the stale-while-revalidate strategy to ensure the page speed. Even if the page fails, the user will update it after refreshing. If your CSS, JS and site are in the same domain, and the file name has the Hash version number, you can use Cache First directly.
    • It is recommended to use Cache First and set certain invalidation events so that the request will not change once.

    Note: Cache only and Cache first must never be used for any resource that is not in the same domain.

    See the Offline Guide for more caching policies

    debugging

    Chrome ://inspect/#service-workers or chrome://serviceworker-internals Firefox uses about:debugging#workers to view service-workers

    compatibility

    Desktop

    Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
    Basic support 40.0 33.0(33.0) [1] Unrealized. 24 Unrealized.

    Mobile

    Feature Android Chrome for Android Firefox Mobile (Gecko) Firefox OS IE Phone Opera Mobile Safari Mobile
    Basic support Unrealized. 40.0 (Yes) (Yes) Unrealized. (Yes) Unrealized.

    Compatible scheme:

    • One great thing about Service Workers is that if you use a browser feature check like the one above, the browser doesn’t support it. Meanwhile, if you are using both AppCache and SW on the same page, a browser that does not support SW but does support AppCache can use AppCache, if both support SW
    • Use ServiceWorker Cache Polyfill to support the ServiceWorker Cache API in older browsers.

    Some other applications for ServiceWorker

    • 1 Background Data Synchronization (Sync event)
    • 2 Response to push events
    • 3 Performance enhancements (such as prefetching resources that the user might need, such as the last few images in an album)

    The practical application

    From the introduction to the Service Worker at the beginning

    ServiceWorker can be independent of any page, once registered it can persist (unless destroyed manually) and be used as a URL accessible to users in its domain

    Therefore, our cache strategy in network programming is particularly important, and the install and active of Service workers on all sites are similar. They do nothing more than pre-cache resource list and cache clearing after update. The logic is not too complicated.

    In view of this situation, we mostly use Google’s official PWA framework :Workbox3 instead, which is just to solve the Service Worker Api(install, active, fetch event to do the corresponding logical processing, etc.) is too complicated.

    Who is using

    Taobao: The Service Worker on the home page of PC has been online for a period of time. After constantly adjusting the cache strategy, the benefits are still obvious. The total page download time drops from 1.7s to 1.4s on average, shortening the download time by nearly 18%. (2018-08-09)

    Blue Fox: Blue Fox is a prototype document application that we often use. It has many static resources such as images, which is ideal for SW cache

    CSDN: When using CSDN, there are often messages pushed by SW

    Wrote last

    This sharing is mainly to introduce the basic knowledge of Service Worker and the principle of offline application. I hope you can learn something from this.

    Note :PWA (Progressive Web Apps) uses modern Web apis and traditional Progressive enhancement strategies to create cross-platform Web applications. These apps are ubiquitous and feature-rich, giving them the same user experience advantages as native apps.
    reference
    • WebWorker profile
    • Web_Workers_API
    • Use Web Workers
    • Service_Worker_API
    • Use Service Workers
    • Sort out basic knowledge of Service Worker
    • Workbox 3: Service workers can be that simple
    • How to uninstall a Service Worker correctly
    • Make PWA work offline through Service Workers
    • Offline guide