For other translations of this series, see JS working mechanism – Xiaobai 1991 column – Nuggets (juejin. Cn)

The scenarios WebWorker uses are limited and may be rarely used if not computationally intensive tasks.

You probably already know that progressive apps are gaining popularity because they aim to create web apps with a smoother user experience and create a native App experience like an App rather than a browser-side look and feel.

One of the main requirements is that it is very stable in networking and loading, and it can be used under poor or even non-existent network conditions.

In this chapter, we’ll take a closer look at Service Workers: what their functionality looks like and what we need to focus on. Finally, we describe some of the unique advantages of Service Workers and some of our experiences with it. For writing purposes, we will replace Service Workers with SerWorker.

An overview of the

If you want to learn all the details of SerWorker, you can start with our previous blog chapter. Serworkers are just one type of Web Worker. See Shared workers for more details:

  • SerWorker runs in our own global scripting context
  • Cannot be associated with a specific Web page
  • Unable to access DOM

The SerWorker API is an exciting addition to the main academy, enabling offline use of your app and giving developers complete control over the behavior of web apps

The life cycle of the SerWorker

A SerWorker is completely separate from your web page and consists of the following phases

  • download
  • The installation
  • The activation

download

This is when the browser downloads the .js file which contains the Service Worker. This is when the browser downloads the.js file containing SerWorker

The installation

To install a SerWorker into your app, you need to register it in your JS code first. When a SerWorker is registered, notify the browser to start a SerWorker installation step in the background.

By registering the Service Worker, You tell the browser where your Service Worker JavaScript file lives. Let’s look at the following code: By registering SerWorker, you tell the browser where your JS files are and take a look at the code

if ('serviceWorker' in navigator) { window.addEventListener('load', The function () {the navigator. ServiceWorker. Register ('/sw. Js). Then (function (registration) {/ / to register the console. The log (' serviceWorker  registration successful'); }, function(err) {console.log('ServiceWorker registration failed: ', err); }); }); }Copy the code

The code checks whether the current environment supports the SerWorker API. If so, register /sw.js SerWorker

Register () can be called every time the page loads — the browser will indicate whether or not the SerWorker is registered and will handle it appropriately.

An important detail of the register() function is the location of the SerWorker file. In this example, you can see that the SerWorker file is under the root of the server. This means that the scope of SerWorker is the entire source. In other words, the SerWorker will accept all fetch events under the domain name (which we’ll discuss later). If we register SerWorker in /example/sw.js, you will see all fetch events for urls starting with /example/ (e.g. /example/page1/, /example/page2/).

During the installation phase, it is best to load and cache some static resources. Once the resources are successfully cached, SerWoker completes the installation. If not, it will try again. Once the installation is successful, you know that static resources are already in the cache.

This is why you need to register after loading. If not necessary, but highly recommended.

Why is that? Let’s say the user visits your app for the first time. At this time, there is no SerWorker, so the browser cannot know in advance whether there is a SerWorker to install. If installed, the browser will free up extra CPU and memory for additional threads that would otherwise be used to render web pages.

The bottom line is that if you just install a SerWokrt on your page, you run the risk of lazy loading and redrawing – not getting users to the page as quickly as possible.

This is important to note when the page is first accessed. Subsequent visits will not be affected by SerWoker. Once a SerWorker is activated on the first access, it can handle load/cache events for subsequent access. This is true, the Service Worker needs to load well to handle the limited network bandwidth.

The activation

After SerWoker is installed, the next step is activation. This step is a huge opportunity to manage the previous cache.

Once activated, the SerWorker controls all pages in scope. The page that registers SerWorker for the first time will not be controlled until it loads again. Once a SerWorker is controlled, it will be in one of the following states

  • Handles fetch and message events triggered by network or message requests from the page
  • Interrupt to save memory

Take a look at its life cycle:

Handles the installation process inside the Service Worker

What happens inside the SerWorker script after the page processes the registration process? It listens for the Install event of the Service Worker instance.

Those are the steps that need to be taken when the install event is handled

  • Open the cache
  • Cache our files
  • Verify that all required resources have been cached

Look at a simple example of how a Service Worker is installed internally:

var CACHE_NAME = 'my-web-app-cache'; var urlsToCache = [ '/', '/styles/main.css', '/scripts/app.js', '/scripts/lib.js' ]; self.addEventListener('install', Event.waituntil (caches. Open (CACHE_NAME)) {// event.waitUntil(caches. Open (CACHE_NAME)) .then(function(cache) { console.log('Opened cache'); return cache.addAll(urlsToCache); })); });Copy the code

If all files have been successfully cached, then SerWoker will be installed. If any files are not downloaded successfully, the installation step will fail. So be careful to protect your files.

Handling the install event is optional, if you have nothing else to do at this step.

The runtime caches the request

This part is dry. Here you will see how to hijack the request and how to return the cache that has been created.

After SerWorker is installed, the SerWorker will receive the FETCH event if the user navigates to another page or refreshes the current page. Here is an example of how to return a cached static resource or perform a new request and cache the return result

Self.addeventlistener ('fetch', function(event) {event.respondwith (// This method queries the request and returns any cached data created by the Service Worker. Caches. Match (event.request). Then (function(response) {// If (response) {return response; } // Copy the request. A request is a stream and can only be used once. Since it has been used once before through the cache, the request needs to be copied in order to use the FETCH in the browser. var fetchRequest = event.request.clone(); // No cache found. So we need to perform the FETCH to initiate the request and return the request data. Return fetch(fetchRequest). Then (function(response) {if(! response || response.status ! == 200 || response.type ! == 'basic') { return response; } // Replication returns data because it is also a stream. Because we want the browser to use the returned data as well as the cache, we have to copy it. Var responseToCache = response.clone(); Caches. Open (CACHE_NAME). Then (function(cache) {// Add the request to the cache for later queries. }); return response; }); })); });Copy the code

See what happens inside:

  • The event.respondWith()Will determine how we’ll respond to thefetch event. We pass a promise from caches.match() which looks at the request and finds if there are any cached results from any of the caches that have been created.
  •  event.respondWith()Will decide how to respondfetchEvents.caches.match()The query request then returns any cached data from the previously created cache and returns a promise.
  • If there is a cache, the response will be restored
  • Otherwise, executefetch
  • Check whether the status code is200. Also check whether the response type isbasicIn this case, requests for third-party resources will not be cached.
  • The response content is added to the cache.

Requests and responses need to be cloned because they are streams. The body of the stream can only be used once. Because both caches and browsers need to use them, they must be copied.

Update Service Worker

When the user accesses your app, the browser will try to re-download the.js file that contains the SerWorker code — this is done in the background.

If the downloaded file is compared to the current SerWorker file, even if it is only one character different, the browser will assume that the file has changed and start a new SerWorker.

The new SerWoker will start and the installation event will be triggered. At this time, the old SerWorker still controls the page of the app, and the new SerWorker will enter a waiting state.

Once the currently open page is closed, the old SerWoker will be blocked by the browser and the newly installed SerWoker will have full control. Its activation event will then be triggered.

Why is all this necessary? This is to avoid the problem of running different versions of the app on different tabs at the same time – which can cause new bugs (such as having different database structures when storing data locally in the browser).

Delete cached data

The most common step in the Activate callback is cache management. You may need to do this if you intend to clear all the old cache of installation steps, and the old SerWorker will suddenly lose the ability to retrieve files from the cache.

Here is an example how you can delete some files from the cache that are not whitelisted (in this case, Having PAGe-1 or page-2 under their names): Here is an example of how to remove files from the cache that are not whitelisted (in this case, name them page-1 or Page-2)

self.addEventListener('activate', function(event) { var cacheWhitelist = ['page-1', 'page-2']; Event.waituntil (// gets all keys in the cache caches.keys(). Then (function(cacheNames) {return promise.all (// iterates through all cache files CacheNames. Map (function(cacheName) {// If the cache file is not in the whitelist, Delete if (cachewhitelist.indexof (cacheName) === -1) {return caches. Delete (cacheName); }})); })); });Copy the code

HTTPS request

When building your app, you can use SerWorker via localhost, but once you publish your product, you need to use HTTPS (which is the last reason to use HTTPS). Service workers can be used to hijack network connections and forge response data. Without HTTPS, web applications are vulnerable to man-in-the-middle attacks.

To ensure security, Service Workers must be registered on the page through HTTPS, so as to ensure that the Service Worker received by the browser is not tampered with during transmission

Browser support

Browser support is getting better:You can track browser support –Jakearchibald. Making. IO/isservicewo….

## Service Workers offers the possibility of more functions

The Service Worker provides some unique features:

  • Push notifications – Allows users to choose to receive push updates from web applications at regular intervals
  • Background synchronization – Allows deferred operations until the network connection is stable. This ensures that users can send data in real time.
  • Periodic synchronization (later supported) – Provides the function for the management to periodically synchronize data in the background
  • Geofencing (future support) – You can customize parameters, known as geofences, that contain the location of interest to the user. Devices are notified when they pass through a geofencing fence, which allows you to provide a useful user experience based on their location

Each of the features mentioned here will be detailed in future articles in this series.