The goal is to reduce time to first meaningful paint.
Find what is content v.s. what is essential UI.
self.addEventListener('install', evt => {
evt.waitUntil(prefetch());
});
function prefetch() {
return self.caches.open(CURRENT_CACHE)
.then(cache => cache.addAll(SHELL_ASSETS));
}
self.addEventListener('activate', evt => {
evt.waitUntil(clearOldCaches());
});
function clearOldCaches() {
return self.caches.keys().then(names => {
return Promise.all(names.map(cacheName => {
if (cacheName === CURRENT_CACHE) {
return Promise.resolve();
}
else {
return self.caches.delete(cacheName);
}
}));
});
}
self.addEventListener('fetch', evt => {
var req = evt.request;
if (isShell(req)) {
evt.respondWith(handleShell(req));
}
else {
evt.respondWith(handleContent(req));
}
});
function cacheFirst(req) {
return self.caches.match(req).then(res => {
return res || self.fetch(req);
});
}
function cacheOnly(req) {
return self.caches.match(req).then(res => {
return res || Promise.reject('not-found');
});
}
function networkFirst(req) {
return self.fetch(req)
.then(res => res.ok ? res : cacheOnly(req))
.catch(() => cacheOnly(req));
}
function networkFirstWithTimeout(req, timeout) {
return new Promise((fulfil, reject) => {
setTimeout(() => fulfil(cacheOnly(req)), timeout);
networkFirst(req).then(fulfil, reject);
});
}
function networkOnly(req) {
return self.fetch(req);
}
function fastest(req) {
return race(networkOnly(req), cacheOnly);
}
function race(promiseA, promiseB) {
return new Promise((fulfil, reject) => {
promiseA.then(fulfil, () => promiseB.catch(reject));
promiseB.then(fulfil, () => promiseA.catch(reject));
});
}
function offlineFallback(req) {
var defaultRequest = getDefault(req, 'by-type');
return cacheOnly(defaultRequest);
}
self.addEventListener('fetch', evt => {
var request = evt.request;
var cacheResponse = cacheOnly(request);
var networkResponse = networkOnly(request);
evt.respondWith(race(
cacheResponse,
networkResponse.then(response => response.clone())
));
evt.waitUntil(networkResponse.then(response => update(request, response.clone())));
});
function update(request, response) {
return self.caches.open(CURRENT_CACHE)
.then(cache => cache.put(request, response));
}