From 79dd3a816327c128aa73424c408230a2a73d5227 Mon Sep 17 00:00:00 2001 From: Sebastian Benz Date: Tue, 20 Dec 2016 08:29:38 +0100 Subject: [PATCH 1/3] Don't cache pages Only use cache to load page after transition. --- public/js/sw-page-transition-client.js | 14 +++++++++----- public/js/sw-page-transition.js | 26 +++++++++++++++----------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/public/js/sw-page-transition-client.js b/public/js/sw-page-transition-client.js index 10fe21df..25152d49 100644 --- a/public/js/sw-page-transition-client.js +++ b/public/js/sw-page-transition-client.js @@ -30,7 +30,7 @@ class PageTransitionClient { * @private */ register() { - this.log('page transition client registered for ' + this.urlWithoutFragment); + this.log('registered for ' + this.urlWithoutFragment); // Register our serviceworker and let it know that we're waiting // for a fetch result if (this.serviceWorker && this.serviceWorker.controller) { @@ -66,10 +66,14 @@ class PageTransitionClient { */ loadTargetPage() { if (this.debug) { + // stay on the loading page return; } - window.location.href = this.originalUrl; - location.reload(); + const url = new URL(this.originalUrl); + // force loading cached result + url.searchParams.append('cache', 1); + this.log('reloading ' + url); + window.location.href = url.toString(); } /** @@ -82,7 +86,7 @@ class PageTransitionClient { handleMessage(evt) { const message = evt.data; if (message.type === 'fetch' && message.url === this.urlWithoutFragment) { - this.log('page transition client: received fetch signal for ' + message.url); + this.log('received fetch signal for ' + message.url); this.serviceWorker.removeEventListener('message', this.handleMessage); this.loadTargetPage(); } @@ -106,7 +110,7 @@ class PageTransitionClient { log(string) { if (this.debug) { - console.log(string); + console.log('[sw-page-transition-client] ' + string); } } diff --git a/public/js/sw-page-transition.js b/public/js/sw-page-transition.js index 9b443c5d..ac0d2000 100644 --- a/public/js/sw-page-transition.js +++ b/public/js/sw-page-transition.js @@ -20,6 +20,7 @@ const DEFAULT_CACHE_NAME = 'sw-page-transitions-cache'; /* eslint-disable no-unused-vars */ + const transition = (function() { /* eslint-enable no-unused-vars */ @@ -32,7 +33,7 @@ const transition = (function() { this._cacheName = cacheName; this._transitionPageMatchers = []; self.addEventListener('message', this.onMessageReceived.bind(this)); - this._debug = true; + this._debug = false; } /** @@ -41,8 +42,8 @@ const transition = (function() { * @param {String} cacheName cache name for page transitions * @return {SwPageTransitionController} return controller */ - cacheName(cacheName) { - this._cacheName = cacheName; + cacheName(name) { + this._cacheName = name; return this; } @@ -72,19 +73,22 @@ const transition = (function() { if (request.mode !== 'navigate') { return Promise.resolve(null); } - this.log('fetchWithPageTransition(' + request.url + ')'); + this.log('fetchWithPageTransition: fetch ' + request.url); + const url = new URL(request.url); + if (url.searchParams.get('cache') === '1') { + url.searchParams.delete('cache'); + this.log('fetchWithPageTransition: returning cached page ' + url); + return caches.match(new Request(url.toString())); + } const transitionPage = this.findTransitionPage(request); // Return null if there is no transition page registered for this request. if (!transitionPage) { + this.log('fetchWithPageTransition: no transition page found'); return Promise.resolve(null); } - // Returned requested page if in cache otherwise the transition page - return caches.match(request).then(response => { - if (response) { - this.log('fetchWithPageTransition: returning cached page'); - } - return response || this.fetchTransitionPage(request, transitionPage); - }); + // Returned the transition page + this.log('fetchWithPageTransition: return transition page'); + return this.fetchTransitionPage(request, transitionPage); } /** From 93d05ddd1f7daf837de10f8857fc0cc69c84a1de Mon Sep 17 00:00:00 2001 From: Sebastian Benz Date: Wed, 21 Dec 2016 16:56:38 +0100 Subject: [PATCH 2/3] Delete old caches on sw update --- public/sw.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/public/sw.js b/public/sw.js index 98fa4a9e..898493e5 100644 --- a/public/sw.js +++ b/public/sw.js @@ -12,6 +12,10 @@ toolbox.options.debug = false; // Use page transitions importScripts('/js/sw-page-transition.js'); /* global transition */ +const VERSION = '2'; +const PREFIX = 'gulliver'; +const CACHE_NAME = `${PREFIX}-v${VERSION}`; + // URL to return in place of the "offline dino" when client is // offline and requests a URL that's not in the cache. const OFFLINE_URL = '/.shell/offline'; @@ -36,6 +40,7 @@ const OFFLINE = [ ]; toolbox.precache(OFFLINE); +toolbox.options.cache.name = CACHE_NAME; // Cache the page registering the service worker. Without this, the // "first" page the user visits is only cached on the second visit, @@ -46,6 +51,7 @@ toolbox.precache( }) ); +// Register and cache page transitions for list and detail page transition.cacheName(toolbox.options.cache.name) .registerPageTransition(/\/pwas\/.*/, TRANSITION_PWA_VIEW) .registerPageTransition(/\/.*/, TRANSITION_PWA_LIST); @@ -59,7 +65,7 @@ toolbox.router.head(/^/, request => { // strategy, except that we cache.match(url) rather than cache.match(request) so // that the HEAD method is ignored on cache.match(). function onlyIfCached(url) { - return caches.open(toolbox.options.cache.name).then(cache => { + return caches.open(CACHE_NAME).then(cache => { return cache.match(url).then(response => { return (response && response.status === 200) ? response : new Response('', { status: 504, @@ -101,9 +107,18 @@ toolbox.router.default = (request, values, options) => { }); }; -// Claim clients so that the very first page load is controlled by a service -// worker. (Important for responding correctly in offline state.) self.addEventListener('activate', () => self.clients.claim()); +// Delete old caches and claim clients so that the very first page load is controlled by a service +// worker. (Important for responding correctly in offline state.) +self.addEventListener('activate', () => + caches.keys().then(cacheNames => + Promise.all( + cacheNames.filter(cacheName => cacheName !== CACHE_NAME) + .map(cacheName => caches.delete(cacheName)) + ).then(self.clients.claim()) + ) +); + // Make sure the SW the page we register() is the service we use. self.addEventListener('install', () => self.skipWaiting()); From 220a80969416029ebb2e323ebe231b9448f8d67c Mon Sep 17 00:00:00 2001 From: Sebastian Benz Date: Wed, 21 Dec 2016 18:08:25 +0100 Subject: [PATCH 3/3] support offline mode --- public/js/sw-page-transition.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/public/js/sw-page-transition.js b/public/js/sw-page-transition.js index ac0d2000..7c25374d 100644 --- a/public/js/sw-page-transition.js +++ b/public/js/sw-page-transition.js @@ -87,7 +87,6 @@ const transition = (function() { return Promise.resolve(null); } // Returned the transition page - this.log('fetchWithPageTransition: return transition page'); return this.fetchTransitionPage(request, transitionPage); } @@ -105,13 +104,20 @@ const transition = (function() { return caches.match(new Request(transitionPage)) .then(response => { if (!response) { - this.log('fetchWithPageTransition: loading page not found in cache'); + this.log('fetchTransitionPage: loading page not found in cache'); return Promise.resolve(null); } + this.log('fetchTransitionPage: return transition page'); // Fetch the actual page and notify transition page when it's ready - this.openCache().then(cache => - cache.add(request).then(() => this.notifyListeners(request.url)) - ); + this.openCache() + .then(cache => cache.add(request) + .then(() => this.notifyListeners(request.url)) + .catch(() => { + // offline + console.log('handling offline case'); + this.notifyListeners(request.url); + }) + ); return Promise.resolve(response); }); }