var appCache = window.applicationCache;
appCache.addEventListener('updateready', function (event) {
if (confirm('Voulez-vous la nouvelle version ?')) {
window.location.reload();
}
});
Lister tout
Ajouter unitairement
Mettre à jour unitairement
Supprimer unitairement
API haut niveau
API bas niveau
Service Workers
Proxy programmabledans le navigateurentre vos pageset votre serveurqui a son propre cache
HTTPShttps://sousdomaine.domaine:port
// page.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(function (registration) {
console.log('SW OK ;->', registration.scope);
})
.catch(function (err) {
console.log('SW KO :-<', err);
});
}
// sw.js (réponse depuis le cache)
self.addEventListener('fetch', function (event) {
event.respondWith(caches.match(event.request));
});
// sw.js (réponse depuis serveur ou depuis le cache)
self.addEventListener('fetch', function (event) {
if (event.request.url.match('/api') {
event.respondWith(/* avec le serveur */);
}
else {
event.respondWith(caches.match(event.request));
}
});
XMLHttpRequest
// page.js
var url = '/api/conferences';
var xhr = new XMLHttpRequest();
var async = false; (1)
xhr.open('GET', url, async);
xhr.responseType = 'json';
xhr.onload = function () {
var conferences = xhr.response;
console.log('confs', conferences);
};
xhr.onerror = function () {
console.log('error');
};
xhr.send();
// sw.js (réponse depuis serveur ou depuis le cache)
self.addEventListener('fetch', function (event) {
if (event.request.url.match('/api') {
event.respondWith(fetch(event.request));
}
else {
event.respondWith(caches.match(event.request));
}
});
Cycle de vied’un Service Worker
// page.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(onSuccess)
.catch(onError);
}
// sw.js
self.addEventListener('install', function (event) {
// le service worker s'installe
});
// sw.js
var CURRENT_CACHE = 'mon-site-v1',
urlsToCache = [
'/',
'/main.css',
'/index.js',
'/logo.jpg'
];
self.addEventListener('install', function (event) {
// le service worker s'installe
});
// sw.js
var CURRENT_CACHE = 'mon-site-v1',
urlsToCache = [
'/',
'/main.css',
'/index.js',
'/logo.jpg'
];
self.addEventListener('install', function (event) {
event.waitUntil(
// attend avant qu'une promise se résolve
);
});
// sw.js
var CURRENT_CACHE = 'mon-site-v1',
urlsToCache = [
'/',
'/main.css',
'/index.js',
'/logo.jpg'
];
self.addEventListener('install', function (event) {
event.waitUntil(
caches.open(CURRENT_CACHE).then(function (cache) {
return cache.addAll(urlsToCache);
})
);
});
self.addEventListener('activate', function (event) {
// le SW essaye de s'activer
});
// page.js
navigator.serviceWorker.register('/sw.js')
.then(function (registration) {
// un objet avec ce que je veux dedans
registration.active.postMessage({
command: 'forceUpdate',
foobar: 42
});
});
// sw.js
self.addEventListener('message', function (event) {
if (event.data.command === 'forceUpdate') {
// mettre à jour le cache kivabien avec le serveur
}
});
// sw.js
self.addEventListener('fetch', function (event) {
if (event.request.url.match('/logout') {
// prevenir tous les onglets de la déconnexion
}
});
// sw.js
self.addEventListener('fetch', function (event) {
if (event.request.url.match('/logout') {
clients.matchAll().then(function (windowClients) {
});
}
});
// page.js
var sw = navigator.serviceWorker;
sw.addEventListener('message', function (event) {
if (event.data.command === 'logout') {
// rediriger vers l'accueil ou le login
// vider le localStorage
// cacher l'avatar
// ...
}
});
La suite...push & notifications........streaming des résponses........................synchronisation...................................geofencing...............................................................( alarmes )
Excuses techniques
User experience
Synchronisation des données
Résolutions des conflits
AppCache = Tout pourri
SW = Prometteur ;-)
Offline-first Web
==> Natif / Web <==
Utilisateur “Presqu’Internet”
Merci ;-)
le “super” public ...................................................... Vous
l'anecdote des toilettes ........................................................... Jake Archibald
les idées pour les schémas ......................................................... Jake Archibald
les articles intéressants .......................................................... Jake Archibald
les articles intéressants .......................................................... Ben Kelly
les articles intéressants .......................................................... Matt Gaunt
les talks qui m'ont inspirés ....................................................... Jake Archibald
les talks qui m'ont inspirés ....................................................... Alex Russel
les icônes des schémas ............................................................. TheNounProject