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 runtimeCaching
code 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.
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.
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.
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.
Service workers are a fundamental part of a PWA. They enable fast loading (regardless of the network), offline access, push notifications, and other capabilities.
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 thesw-toolbox
code and configuration alongside its own configuration. Using theruntimeCaching
configuration option insw-precache
(see below) is a shortcut that accomplishes what you could do manually by importingsw-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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With