Skip to content

Instantly share code, notes, and snippets.

@liitfr
Last active October 28, 2017 02:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save liitfr/7322a0bde4da5aef09dbee24336db35b to your computer and use it in GitHub Desktop.
Save liitfr/7322a0bde4da5aef09dbee24336db35b to your computer and use it in GitHub Desktop.
Service worker & offline first
# ...
<Files sw.js>
# FileETag None # LIIT : disabled this to check if it allows cdn update
# Header unset ETag # LIIT : disabled this to check if it allows cdn update
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</Files>
# ...

Reminder

Don't forget to hash assets & update references everywhere (including sw.js).
However sw.js file name shouldn't be hashed.
Code given in common.js can be included in your main js file or inlined in your page.

Inspiration : https://jakearchibald.com/2016/caching-best-practices/

CDN Cache Issue

Currently investigating with OVH CDN cache because sw.js update isn't always triggered.
If your service worker doesn't reflect last version of your website, current solution is to empty CDN cache

import * as SnackBar from 'node-snackbar';
// ....
// Service Worker
// https://github.com/GoogleChrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js
const offlineMsg = 'Vous êtes passé(e) en mode déconnecté.';
const onlineMsg = 'Vous êtes de nouveau connecté(e).';
const redundantMsg = 'SW : The installing service worker became redundant.';
const errorMsg = 'SW : Error during service worker registration : ';
const refreshMsg = 'Du nouveau contenu est disponible sur le site, vous pouvez y accéder en rafraichissant cette page.';
const availableMsg = 'SW : Content is now available offline.';
const close = 'Fermer';
const refresh = 'Rafraîchir';
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
function updateOnlineStatus() {
SnackBar.show({
text: navigator.onLine ? onlineMsg : offlineMsg,
backgroundColor: '#000000',
actionText: close,
});
}
window.addEventListener('online', updateOnlineStatus);
window.addEventListener('offline', updateOnlineStatus);
navigator.serviceWorker.register('sw.js').then((reg) => {
reg.onupdatefound = () => {
const installingWorker = reg.installing;
installingWorker.onstatechange = () => {
switch (installingWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
SnackBar.show({
text: refreshMsg,
backgroundColor: '#000000',
actionText: refresh,
onActionClick: () => { location.reload(); },
});
} else {
console.info(availableMsg);
}
break;
case 'redundant':
console.info(redundantMsg);
break;
default:
break;
}
};
};
}).catch((e) => {
console.error(errorMsg, e);
});
});
}
// ....
const wbBuild = require('workbox-build');
// ....
// Service Worker generation
gulp.task('bundle-sw', gulp.series('generate-sitemap', () => {
return wbBuild.generateSW({
globDirectory: gulpOutputDir,
swDest: `${gulpOutputDir}/sw.js`,
globPatterns: ['**/*.{html,png,xml,css,ico,txt,json,svg,js,map,gif,jpeg,jpg,bmp,cur,webp}'],
skipWaiting: true,
clientsClaim: true,
})
.then(() => {
console.warn('Service worker generated.');
})
.catch((err) => {
console.error(`[ERROR] This happened: ${err}`);
});
}));
// ....
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment