Service Worker: Make web pages accessible without a network

This article is original, please indicate the address in the form of a link for reprinting: https://kymjs.com/code/2017/02/15/01

↑↑↑↑OSC's blog layout is almost impossible to read on a mobile phone, just visit the original text directly ↑↑↑↑

introduce

First of all, I would like to write to all students who are developing on the mobile terminal: PWA (Progressive Web Apps) must be the future trend of mobile development, and learn and cherish it.
Progressive Web Apps are more convenient than applets. For first-time users, they can access them directly in the browser without installing an app. Even in a poor network environment, it can be loaded quickly, and can push relevant messages. It can also be added to the desktop or browser home screen like a native application, enabling a full-screen browsing experience.
What is the relationship between PWA and Service Worker? Service Worker is a background process running in the browser. jsBased on it, it can realize message push, silent update, intercept and process network requests, including programmable response cache management. It is the core of PWA.
Open Source Lab ( https://www.kymjs.com ) has enabled Service Worker, and now as long as the articles you have visited can be accessed offline in mainstream browsers (including PCs and mobile phones).

working principle

Service worker is a js script that is completely independent of web pages and has its own life cycle.
Each service worker corresponds to a cache pool, and each cache pool has multiple cache repositories.
First talk about its declaration cycle, borrowing a picture from Google:

Serice Worker

If there is no cacheName corresponding to the website install, the installevent .
If installit fails, exit and wait for the next access to restart; otherwise, trigger an activateevent.
In activate, determine whether the current page is in the filesToCache list declared above, and if so, take over the display of the web page.
After taking over the web page, if the current memory is insufficient, it will be killed; otherwise, it will wait for processing fetchand messageevents. One of these two events is when the network requests, or when other web pages send a message. This article only talks about how to make your web page accessible even without a network. It does not talk about these two events. The next article will talk about the in-depth use of service workers.

Start with use

Ready to work

First of all, your site must support httpsit (this is also the reason why you made an error when visiting the open source laboratory in the past two days, and you are turning to https for the whole site).
Second, you need to know at least a little bit of jsdevelopment .
Finally, you must have a version of Chrome 52 or above for debugging.

Register Service Worker

First, create a service-worker.jsfile .
The service-worker.js file must be placed in the root directory because the scope of service workers is determined by their location in the directory structure.

Then you need to check whether the browser supports service workers, if so, register the service worker, and add the following code to the page to be loaded js.

if('serviceWorker' in navigator) {  
	//注册上一步创建的js文件
    navigator.serviceWorker  
        .register('/service-worker.js')  
        .then(function() { console.log('Service Worker Registered'); });  
}

load cache

When a user visits a page with a registered service worker, an event called will be triggered install, so we first listen to this event.

var cacheName = 'oslab-kymjs-blog';
var filesToCache = [];

self.addEventListener('install', function(e) {
  console.log('[ServiceWorker] Install');
  e.waitUntil(
    caches.open(cacheName).then(function(cache) {
      console.log('[ServiceWorker] Caching app shell');
      return cache.addAll(filesToCache);
    })
  );
});

After listening to the installevent, go to the cache pool to open the cache repository named oslab-kymjs-blog.
Each service worker corresponds to a cache pool, and each cache pool has multiple cache repositories.
As soon as the cache is open, cache.addAll() is called with a list of urls, and the resources are loaded and the response is added to the cache.
One thing to note is that in the cache.addAll() method, if a file download fails, the entire cache will fail, and the service worker installevent will also fail. And if it installfails, then the service worker will not work at all. Therefore, we must pay attention to the fact that the file list must not be too long. The longer the file list, the higher the probability of failure. The larger the page to be cached, the higher the probability of failure.

debugging

Debugging Service Workers with Chrome Developer Tools is very convenient.
First run your local server (my blog is generated by jekyll, so I use the jekyll service directly), then the three dots in the upper right corner of Chrome, More Tools, Developer Tools. (Mac shortcut cmd+opt+i)
switch to the Application view and
you should see a page like this

Serice Worker

The first run should show empty, nothing to see, just refresh it. But if you still can't see it after refreshing, it means that the currently opened page does not have a registered service worker, check whether the registration step jsis loaded.

Be sure to check [update on reload] before refreshing, otherwise a new service worker will be started every time you refresh, and then because it is executed serially, it will wait for the previous one to finish, otherwise you have to manually click [skipWaiting].
Then if you check [update on reload], you may see this warning, it doesn't matter, just ignore it.

Serice Worker

delete useless cache

The activateevent . So we listen to activate and update the cache here.

self.addEventListener('activate', function(e) {  
  console.log('[ServiceWorker] Activate');  
  e.waitUntil(  
    caches.keys().then(function(keyList) {  
      return Promise.all(keyList.map(function(key) {  
        console.log('[ServiceWorker] Removing old cache', key);  
        if (key !== cacheName) {  
          return caches.delete(key);  
        }  
      }));  
    })  
  );  
});

The above code means that if activate is executed, first determine whether the cacheName of the cache warehouse in the cache pool is the same as the cacheName we declared, if not, clear the useless cache in the cache pool (download a new cache in install, delete it in activate old cache). So it is recommended that you add a version number to the end of the cacheName so that the service worker always loads the latest cache.

At this point, we have fully connected the service worker for our blog.
If not, you can use the service worker of my blog as a reference, and see my writing method Open source laboratory anti-leech .

Finally, attach Google's introduction to Service Worker: an Introduction .

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324973699&siteId=291194637