An overview of the

Service Worker is a new feature of HTML5, mainly used for persistent offline caching.

  • In this paper, the source code

Why use ServiceWorker

In corporate business, performance optimization requirements are often addressed, and traditional performance optimization methods are used to meet most business scenarios. However, if the target user’s mobile phone performance and network is generally poor (such as southeast Asia, India and other overseas markets), the bottleneck lies in DNS query,TCP establishment time, the use of conventional optimization means is insufficient. At this time, our project team tried to adopt the offline caching scheme, that is, static resources are cached locally, and local files are read by intercepting proxy requests to speed up access.

The purpose of ServiceWorker

The only purpose of this API is to free up the main thread. The Web Worker is detached from the main thread, giving it some complicated and time-consuming work to do, and telling the main thread through the postMessage method when it is finished. The main thread uses the onMessage method to get feedback on the results of the Web Worker.

Functions and features

  • Service WorkerHave their own independentworkerThread, independent of the current web page thread
  • Offline cache static resources
  • Intercept proxy requests and responses
  • You can customize the response content
  • Can be achieved bypostMessageSends a message to the main thread
  • You cannot manipulate the DOM directly
  • Must work in HTTPS environment or localhost / 127.0.0.1 (own security mechanism)
  • throughPromiseAsynchronous implementation
  • Service WorkerInstallation (installing) will persist unless manually uninstalled (unregister)

The life cycle

The life cycle of a Service Worker is completely independent of the web page

  • registered (register)
  • The installation (install)
  • The activation (activate)

Typically, using a service worker requires only the following steps:

  • 1. Check whether it is supportedserivceworker

First, check whether the current environment supports service workers by using ‘serviceWorker’ in Navigator.

  • Register (register) 2.

If support, you can use the navigator. ServiceWorker. Register (‘. / sw. Js’), registered in the main thread service worker. If the registration is successful, the service worker will run in the ServiceWorkerGlobalScope environment. Note that the current environment cannot manipulate the DOM and is independent of the main thread (i.e., threads do not block with each other).

  • 3. Install (install)

The service worker is then installed in the background, and in the process, some static resource files are cached.

  • 4. Activate (active)

After the installation is successful, it is ready to activate the service worker. Usually, in the active state, operations such as cache clearing and service worker updating are performed.

  • 5. Use (activing)

Once activated, the service worker can control the current page. It should be noted that only after the service worker is successfully activated can it have the ability to control the page. Generally, when the page is accessed for the first time, the service worker is successfully created for the first time but not activated. Only after the page is refreshed and accessed again can the service worker have the ability to control the page.

  • 6. Uninstall (unregister)

Cache granulation

  1. Cache *.html static resource files

Caching benefits and costs

  • earnings
    1. It saves the TCP connection establishment time and speeds up the first screen loading speed
    2. Reduce the load on static resource servers
  • The cost of
    1. Data inconsistency problem (update policy)
    2. Code maintenance cost (cache files)

Project presentations

After the ServerWorker is installed for the first time for this project, you can see the following information on the console:

View the static resource information of the request:

As you can see, when ServiceWorker is first installed, static resources read are not cached.

As you can see, static resources are cached by the Serviceworker.

Check the current serviceworker installation:

As you can see, the ServiceWorker is already active.

Finally, take a look at the offline functionality:

Isn’t it amazing that our pages can display data when offline? The principle of offline is to use the fetch and cacheStorage interfaces of ServiceWorker to intercept requests and cache responses

The source code to achieve

The source code to achieve the following functions:

  • Forced to updatethroughself.skipWaiting()If a new one is detectedservice workerThe file is immediately replaced with the old one.
  • Caching static resources cache.addAll(cacheFiles)Through this interface
  • Intercept requestBy listeningfetchEvent that intercepts all requests for the current pageself.addEventListener('fetch',function(e){})
  • Cache the responseAdd the response content to the cachecache.put(evt.request, response)
// Cache the static resource file list
let cacheFiles = [
  './test.js'.'./index.html'.'./src/img/yy.png'
]
// The version used by serviceworker
let __version__ = 'cache-v2'

// Cache static resources
self.addEventListener('install'.function (evt) {
  // Force an update to sw.js
  self.skipWaiting()
  evt.waitUntil(
    caches.open(version).then(function (cache) {
      return cache.addAll(cacheFiles)
    })
  )
})

// Cache update
self.addEventListener('active'.function (evt) {
  evt.waitUntil(
    caches.keys().then(function (cacheNames) {
      return Promise.all(
        cacheNames.map(function (cacheName) {
          if(cacheName ! == version) {return caches.delete(cacheName)
          }
        })
      )
    })
  )
})

// Request interception
self.addEventListener('fetch'.function (evt) {
  console.log('Handle fetch event :', evt.request.url)
  evt.respondWith(
    caches.match(evt.request).then(function (response) {
      if (response) {
        console.log('Cache matches to res:', response)
        return response
      }
      console.log('Cache does not match request, ready to fetch from network', caches)
      return fetch(evt.request).then(function (response) {
        console.log('fetch fetch response:', response)
        caches.open(version).then(function (cache) {
          cache.put(evt.request, response)
          return response
        })
      })
    }).catch(function (err) {
      console.error('FETCH interface error', err)
      throw err
    })
  )
})

Copy the code

Please refer to: source code address