Using service Workers to pre-cache the application shell

Source: Internet
Author: User
Tags addall blank page

Progressive Web Apps is fast and installable, which means it can be used in an online, offline, intermittent, or slow network environment. To achieve this goal, we need to use a service worker to cache the application shell to ensure that it is always available and reliable at all times.

If you are unfamiliar with service workers, you can learn about what it can do, how its life cycle works, and so on, by reading about service workers.

Service workers provides a feature that should be understood as progressive enhancement, which is only used for browsers that support service workers. For example, with service workers you can cache the application shell and the data needed for your application, so this data is still available in an offline environment. If the browser does not support service workers, the code that supports offline does not work, and users can get a basic user experience. Using feature detection to build up some small overhead, it does not have a destructive effect on older browsers that do not support service workers.

Registering a service worker

The first thing to do to make an app work offline is to register a service worker, a script that allows it to run in the background, without requiring the user to open the Web page, or other interactions.

This only takes two simple steps:

    1. Create a JavaScript file as a service worker
    2. Tell the browser to register this JavaScript file as a service worker

The first step is to create an empty file under your app's root directory called service-worker.js . This service-worker.js file must be placed in the directory, because service workers is scoped to its location in the directory structure.

Next, we need to check whether the browser supports service workers, and if so, register the service worker and add the following code to app.js the.

If(' Serviceworker ' Inch Navigator)  {   
    Navigator. Serviceworker  
        . ( '/service-worker.js '  
        . (function () {< Span class= "PLN" > Console. "Service Worker registered '  
}



Caching Resources for a site

When the service worker is registered, an event is triggered when the user accesses the page for the first time install . In the callback function of this event, we are able to cache the resources that all applications need to reuse.

When the service worker is activated, it should open the cache object and store the resources needed for the application shell. Add the following code to your service-worker.js (you can find it in your-first-pwapp-master/work ):

VarCacheName= ' Weatherpwa-step-6-1 ';
VarFilestocache= [];

Self.AddEventListener(' Install ', function(E) {
Console.Log(' [Serviceworker] Install ');
E.Waituntil(
Caches.Open(cachename). then (function (cache< Span class= "pun" >) {
      Consolelog (
      return Cache.< Span class= "PLN" >addall (filestocache     })
  });
/span>

First, we need to provide a cached name and take advantage of opening the cache caches.open() object. The cache name provided allows us to add a version to the cached file or separate the data so that we can easily upgrade the data without affecting other caches.

Once the cache is opened, we can call cache.addAll() and pass in a list of URLs and then load the resources and add the responses to the cache. Unfortunately for cache.addAll() atomic operations, if a file cache fails, the entire cache will fail!

Good. Let's get familiar with how to use Devtools and learn how to use Devtools to debug service workers. Before you refresh your Web page, open Devtools, opening the Service Worker 's pane from the application panel. It should be like this:

When you see such a blank page, this means that the currently open page does not have a service Worker already registered.

Now reload the page. The Service Worker's pane should look like this:

When you see this information, this means that the page has a service worker running.

Now let's demonstrate the problems you might encounter when using service workers. To demonstrate, we will add the following event listener for the install in Service-worker.js to the Activate event listeners.

Self.addeventlistener (' Activate ', function (e) {
Console.log (' [Serviceworker] Activate ');
});
This will emit the Activate event when the service worker starts to start.

Open Devtools and refresh the Web page, switch to the Service worker pane of the Application panel, and click Inspect in the service worker that has been activated. In theory, [Serviceworker] Activate information will appear in the console, but this does not happen. Now go back to the Service worker pane and you will find that the new service worker is in the "Waiting" state.

Simply put, the old service worker will continue to control the page until the label is closed. Therefore, you can close and reopen the webpage or click the skipwaiting button, but a long-term solution is to enable Update on Reload in the Service worker pane in Devtools. When the check box is selected, the Service worker will force the update every time the page reloads

Enable the update on reload check box and reload the page to confirm that the new service worker is activated.

Note: you may see an error message similar to the following in the Service worker pane in the application panel, but you can safely ignore the error message.

Ok, now let's complete the code for the Activate event handler to update the cache.

Self.addeventlistener (' Activate ', function (e) {
Console.log (' [Serviceworker] Activate ');
E.waituntil (
Caches.keys (). Then (function (keylist) {
Return Promise.all (function (key) {Keylist.map
Console.log (' [Serviceworker] removing old cache ', key);
if (key!== cachename) {
return Caches.delete (key);
}
}));
})
);
});
Make sure that you modify the CacheName after each service worker modification, which ensures that you can always get the latest version of the file from the cache. After a while, it's important to clean up the cache and delete useless data.

Finally, let's update the list of cached files that the app shell needs. In this array, we need to include all of the files that our application needs, including images, JavaScript, stylesheets, and so on.

var Filestocache = [
‘/‘,
'/index.html ',
'/scripts/app.js ',
'/styles/inline.css ',
'/images/clear.png ',
'/images/cloudy-scattered-showers.png ',
'/images/cloudy.png ',
'/images/fog.png ',
'/images/ic_add_white_24px.svg ',
'/images/ic_refresh_white_24px.svg ',
'/images/partly-cloudy.png ',
'/images/rain.png ',
'/images/scattered-showers.png ',
'/images/sleet.png ',
'/images/snow.png ',
'/images/thunderstorm.png ',
'/images/wind.png '
];
My application is not working offline yet. We have cached the components of the app shell, but we still need to load them from the local cache.

Load app Sheel from cache

Service workers can intercept requests initiated by Progressive Web APP and return responses from the cache. This means that we can decide how to handle these requests and decide which network responses will be our caches.

Like what:

Self.addeventlistener (' Fetch ', function (event) {
Do something interesting and the fetch here
});
Let's load the app shell from the cache. Add the following code to Service-worker.js:

Self.addeventlistener (' Fetch ', function (e) {
Console.log (' [Serviceworker] Fetch ', e.request.url);
E.respondwith (
Caches.match (e.request). Then (function (response) {
Return Response | | Fetch (e.request);
})
);
});
From the Inside Out, Caches.match () obtains the requested content from the fetch event triggered by the network request and determines whether the requested resource exists in the cache. The content in the cache is then responded to, or the FETCH function is used to load the resource (if the resource is not in the cache). Response finally returns to the Web page via E.respondwith ().

Test

Your app can now be used offline! Let's try it!

Refresh the page first, then go to the application panel in the Cache Storage pane of the Devtools. Expand the section and you should see the name of your app shell cache on the left. When you click on your Appshell cache, you will see all the resources that have been cached.

Now, let's test the offline mode. Go back to the Service Worker pane in Devtools, and enable the check box for Offline. When enabled, you'll see a yellow warning icon next to the Network pane. This means that you are offline.

Refresh the webpage and you will find that your webpage is still working!

The next step is to modify the logic of the application and service worker so that the meteorological data can be cached and the latest cached data can be displayed when the application is offline.

TIP: If you want to clear all saved data (localstoarge,indexeddb data, cache files) and remove any service worker, you can devtools in the application panel in the clear Storage clear.


Beware of marginal problems

As mentioned before, this code must not be used in the production environment, because there are many non-processing boundary conditions.

The cache relies on updating the cache name every time the content is modified

For example, the caching method requires you to update the cache name every time you change the content. Otherwise, the cache will not be updated and the old content will always be returned by the cache. Therefore, make sure that you update the cache name every time that you modify your project.

All resources need to be re-downloaded after each modification

Another drawback is that when a file is modified, the entire cache needs to be re-downloaded. This means that even if you modify a simple spelling error, the entire cache is re-downloaded. This is not very efficient.

The browser's cache may block updates to the service worker's cache

Another important warning. The resource requested during the first installation is directly over HTTPS, and this time the browser does not return the cached resource, except that the browser may return the old cache resource, which causes the service worker's cache to not be updated.

The current Cache-first strategy in the production environment

Our app uses a prioritized cache policy, which causes all subsequent requests to be returned from the cache without asking the network. The policy of priority caching is easy to implement, but it also poses many challenges for the future. Once the home page and the registered service worker are cached, it will be difficult to modify the service worker configuration (because the configuration depends on its location) and you will find that the site you are deploying is difficult to upgrade.

How can I avoid these marginal problems

How do we avoid these marginal problems? Using a library, such as Sw-precache, provides granular control over when resources expire, ensuring that requests go directly through the network and helping you with all the tricky issues.

Real-time test service workers tips

Debugging a service workers is an adjustable thing, when it comes to caching, when you expect the cache to be updated, but in fact it doesn't, things become like a nightmare. Between the service worker's typical life cycle and your code, you'll quickly get frustrated. Fortunately, here are some tools to make your life easier.

Other tips:

Once the service worker is logged off (unregistered). It will continue to function until the browser is closed.
If your app opens multiple windows, the new service worker does not work until all the windows are refreshed and the new service worker is used.
Logging off a service worker does not empty the cache, so if the cache name is not modified, you may continue to get the old data.
If a service worker already exists, and another new service worker is already registered, the new service worker will not take over control, knowing that the page is refreshed again, unless you use an immediate control method.

Using service Workers to pre-cache the application shell

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.