Skip to content

Instantly share code, notes, and snippets.

View osvaldasvalutis's full-sized avatar

Osvaldas Valutis osvaldasvalutis

View GitHub Profile
if(criticalResources.includes(url.pathname))
addToCache(criticalsCacheName, request, responseCopy);
else if(type.startsWith('image'))
addToCache(imagesCacheName, request, responseCopy);
else
addToCache(otherCacheName, request, responseCopy);
const trimCache = (cacheName, maxItems) => {
caches.open(cacheName).then(cache => {
cache.keys().then(keys => {
if(keys.length > maxItems)
cache.delete(keys[0]).then(trimCache(cacheName, maxItems));
});
});
};
self.addEventListener('message', event => {
if('serviceWorker' in navigator) {
navigator.serviceWorker.register('/serviceworker.js');
if(navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage({'command': 'trimCache'});
}
}
const clearOldCaches = () => {
return caches.keys().then(keys => {
return Promise.all(keys.filter(key => !key.startsWith(version)).map(key => caches.delete(key)));
});
};
self.addEventListener('activate', event => {
event.waitUntil(clearOldCaches().then(() => self.clients.claim()));
});
const addToCache = (cacheName, request, response) => {
caches.open(cacheName).then(cache => cache.put(request, response));
};
const version = '1-',
criticalsCacheName = `${version}critical`,
otherCacheName = `${version}other`,
imagesCacheName = `${version}images`;
event.respondWith(caches.match(request).then(response => {
return response // cache-first
|| fetch(request).then(response => { // network
// ...
})
.catch(() => { // offline
if(type.startsWith('image')) {
return caches.match('/offline.jpg');
}
else {
event.respondWith(caches.match(request).then(response => {
return response // cache-first
|| fetch(request).then(response => { // network
// ...
})
.catch(() => { // offline
if(type.startsWith('image')) {
return new Response('<svg...', {headers: {'Content-Type': 'image/svg+xml', 'Cache-Control': 'no-store'}});
}
else {
self.addEventListener('fetch', event => {
var type = event.request.headers.get('Accept');
// network-first for HTML documents
if(type.includes('text/html')) {
event.respondWith(
// respondWith code from network-first section
);
}
// cache-first for assets
else {
self.addEventListener('fetch', event => {
event.respondWith(
// check if the resource was cached before
caches.match(event.request).then(response => {
// serve the resource if cached, otherwise fetch it through the network
return response || fetch(event.request).then(response => {
// cache the newly fetched resource and serve it
let responseCopy = response.clone();
addToCache(event.request, responseCopy); // this is a custom function, I'll elaborate on it later
return response;