Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a service worker built with Google's sw-precache really be networkFirst?

I run the website https://www.igluonline.com running Hugo and I recently installed a service worker following Google's sw-precache.

This is the Config file:

module.exports = {
  staticFileGlobs: [
    'dist/css/**.css',
    'dist/**/*.html',
    'dist/images/**.*',
    'dist/js/**.js'
  ],
  skipWaiting: true,
  stripPrefix: 'dist',
  runtimeCaching: [{
    urlPattern: /\/*/,
    handler: 'networkFirst'
  }]
};

Considerations:

Although sometimes the automatic generated code runs into some erros, the service worker works properly and deliver the offline experience both on web and mobile.

Also it has cache-control set to max-age=0 and when I push a new code it makes the update.

Problem:

I set the runtimeCaching handler to networkFirst and according to Google's sw-toolbox API (which is present in sw-precache when using runtimeCaching) it should get the page preferably from the http call and if there is no connection it should fallback to the cache.

But when I refresh my code and open a new window to test (note that I do close all tabs and windows running the website prior to the update), it will show the cached page. It will naturally download the new service worker and on second reload update the page, but I don't expect my visitors to double refresh my homepage every time to get new content.

I try changing the runtimeCachingcode to the following hoping to get at least my homepage to load directly from the network, but I had no luck:

runtimeCaching: [{
    urlPattern: /\//,
    handler: 'networkOnly'
  },{
    urlPattern: /\/*/,
    handler: 'networkFirst'
  }]

Now I'm not sure if the desired PWA experience is like that - meaning that users have to reload twice or at least visit two pages to see the refreshed code - or if I'm making some mistake. I'd really appreciate a consideration.

like image 427
André Lucas Avatar asked May 06 '17 18:05

André Lucas


People also ask

What is a service worker Chrome?

Service workers are specialized JavaScript assets that act as proxies between web browsers and web servers. They aim to improve reliability by providing offline access, as well as boost page performance.

How do I activate a service worker?

Updating your service workerIt is only activated when there are no longer any pages loaded that are still using the old service worker. As soon as there are no more such pages still loaded, the new service worker activates. While this happens, the previous version is still responsible for fetches.

What is a service worker browser?

Service Worker is a script that works on browser background without user interaction independently. Also, It resembles a proxy that works on the user side. With this script, you can track network traffic of the page, manage push notifications and develop “offline first” web applications with Cache API.

What is a service worker PWA?

Service workers are a fundamental part of a PWA. They enable fast loading (regardless of the network), offline access, push notifications, and other capabilities.


1 Answers

When generating service-workers, the easiest way to get the policy you want, is by using sw-precache with sw-toolbox.

When generating a new service-worker withsw-precache, you can also get the sw-toolbox code at the end of the generated file by passing the correct configuration options.

According to the sw-precache Documentation:

The sw-precache module has the ability to include the sw-toolbox code and configuration alongside its own configuration. Using the runtimeCaching configuration option in sw-precache (see below) is a shortcut that accomplishes what you could do manually by importing sw-toolbox in your service worker and writing your own routing rules.

This is an example of the runtimeCaching option showed on the sw-precache documentation:

runtimeCaching: [{
  urlPattern: /^https:\/\/example\.com\/api/,
  handler: 'networkFirst'
}, {
  urlPattern: /\/articles\//,
  handler: 'fastest',
  options: {
    cache: {
      maxEntries: 10,
      name: 'articles-cache'
    }
  }
}]

You can use this option alongside your configuration of choice.

For example you can use a configuration file as stated in the documentation:

There's support for passing complex configurations using --config . Any of the options from the file can be overridden via a command-line flag. We strongly recommend passing it an external JavaScript file defining config via module.exports. For example, assume there's a path/to/sw-precache-config.js file that contains:

module.exports = {
  staticFileGlobs: [
    'app/css/**.css',
    'app/**.html',
    'app/images/**.*',
    'app/js/**.js'
  ],
  stripPrefix: 'app/',
  runtimeCaching: [{
    urlPattern: /this\\.is\\.a\\.regex/,
    handler: 'networkFirst'
  }]
};

That file could be passed to the command-line interface, while also setting the verbose option, via

$ sw-precache --config=path/to/sw-precache-config.js --verbose

This provides the most flexibility, such as providing a regular expression for the runtimeCaching.urlPattern option.

Or you can use a JSON file:

We also support passing in a JSON file for --config, though this provides less flexibility:

{
  "staticFileGlobs": [
    "app/css/**.css",
    "app/**.html",
    "app/images/**.*",
    "app/js/**.js"
  ],
  "stripPrefix": "app/",
  "runtimeCaching": [{
    "urlPattern": "/express/style/path/(.*)",
    "handler": "networkFirst"
  }]
}

This example uses the JS file for the configuration options:

$ sw-precache --config=path/to/sw-precache-config.js --verbose

After executing the command and generating the service-worker with this configurations, you can handle the precache and policies much easier than with just sw-precache.

You can configure your policies directly in the file or add them manually at the bottom of your service-worker code.

Here is the example of the bottom part of the generated code:

//sw-precache generated code...

// *** Start of auto-included sw-toolbox code. ***
/*
 Copyright 2016 Google Inc. All Rights Reserved.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/ 
//(!function(e){if("object"==typeof exports&&"undefined"!=typeof module))...

// *** End of auto-included sw-toolbox code. ***

// Runtime cache configuration, using the sw-toolbox library.

toolbox.router.get(/this\\.is\\.a\\.regex/, toolbox.networkFirst, {});

toolbox.options.debug = true;

//Here you can configure your precache:

toolbox.precache([
    '/',
    '/assets/background.png',
    '/assets/logo.png',
    '/assets/application.css',
]);

//And here you can configure your policies for any route and asset:

toolbox.router.get('/', toolbox.fastest);
toolbox.router.get('/assets/background.png', toolbox.fastest);
toolbox.router.get('/assets/logo.png', toolbox.fastest);

//Here is the Network First example

toolbox.router.get('/myapp/index.html', toolbox.networkFirst);

I've found this much more effective and flexible than using just sw-precache.

Here you can find the sw-toolbox Usage Guide for more info on the configuration.

like image 56
Jorge Cuevas Avatar answered Oct 13 '22 23:10

Jorge Cuevas