A popular pattern for service workers is to use them to cache the app shell or dependent assets required to make the app functional so when the app is offline it will still load. This approach also helps with performance since the app will load more quickly each time it’s run. When a resource needs to be fetched, the service worker will try to load it from the cache first, then fall back to the network.
Replace the code inside the service-worker.js with the following code:
// use a cacheName for cache versioning
var cacheName = 'todos_offline_cache:v1'
var goodCaches = [];
goodCaches.push(cacheName);
goodCaches.push('CordovaAssets');
// during the install phase you usually want to cache static assets
self.addEventListener('install', function(e) {
console.log('[ServiceWorker] Install!');
e.waitUntil(
caches.open(cacheName).then(function(cache) {
return cache.addAll([
'/index.html',
'/manifest.json',
'/css/app.css',
'/css/app.ios.css',
'/css/app.material.css',
'/js/app.js',
'/js/todos.js',
'/js/init-styles.js',
'/lib/framework7/css/framework7.ios.colors.min.css',
'/lib/framework7/css/framework7.ios.min.css',
'/lib/framework7/css/framework7.ios.rtl.min.css',
'/lib/framework7/css/framework7.material.colors.min.css',
'/lib/framework7/css/framework7.material.min.css',
'/lib/framework7/css/framework7.material.rtl.min.css',
'/lib/framework7/js/framework7.min.js',
'/css/framework7-icons.css',
'/css/Framework7Icons-Regular.eot',
'/css/Framework7Icons-Regular.ttf',
'/css/Framework7Icons-Regular.woff',
'/css/Framework7Icons-Regular.woff2',
'/lib/framework7-vue/framework7-vue.min.js',
'/lib/vue/vue.min.js',
'/img/Default-Portrait.png',
'/img/logo.png',
'/img/icons/apple-touch-icon.png',
'/img/icons/mstile-150x150.png',
'/img/icons/safari-pinned-tab.svg',
'/img/icons/favicon-16x16.png',
'/img/icons/favicon-32x32.png',
'/img/icons/favicon.ico',
'/img/icons/icon-128x128.png',
'/img/icons/icon-144x144.png',
'/img/icons/icon-152x152.png',
'/img/icons/icon-192x192.png',
'/img/icons/icon-256x256.png',
'/img/icons/icon-512x512.png',
]).then(function() {
self.skipWaiting();
});
})
);
});
self.addEventListener('activate', function(event) {
console.log('[ServiceWorker] Activate');
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheKey) {
console.log("** Cache key " + cacheKey);
if (goodCaches.indexOf(cacheKey) === -1) {
console.log("Deleting cache " + cacheKey);
return caches.delete(cacheKey);
}
})
);
})
);
});
self.addEventListener('fetch', function(event) {
console.log('Handling fetch event for ' + event.request.url);
event.respondWith(
caches.match(event.request).then(function(response) {
if (response) {
console.log('Found response in cache:', response);
return response;
}
console.log('No response found in cache. Fetch from network...');
return fetch(event.request);
})
);
});
<img logo.png>
tag in index.html from the last exercise, you won’t need that anymore.phonegap serve
service-worker
to see what code is running, and make sure there are no install errors or skipWaiting()
events.You should now see console statements from the code added above.
Your service worker code may fail if you have a typo, or if your resource list in the install step does not resolve to the right path, then the promise will not resolve and install will not complete. To test if that’s the problem, comment out that whole block from
caches.open(cacheName).then(function(cache) {return cache.addAll([...])
on and run again.
You will want to try this lesson with your app hosted somewhere to get the full experience. You could host the app securely using GitHub Pages or use a solution like Firebase (covered in lesson 8). Or simply check out the hosted demo here for how the offline handling works.
You can also view the Cache Storage items the service worker has stored in the Application tab as shown in the screenshot below:
You will sometimes need to refresh to see the latest cache, right click on Cache Storage to do so.
service-worker.js
is. You may be able to click to have it skipWaiting
or unregister
if needed.activate
event has handling to delete old versions of caches that are left around. There’s a quota of storage that needs to be managed so you will want to be sure to clean up old versions when a new service worker no longer needs it.