Last active
August 28, 2018 09:28
-
-
Save eusonlito/cbfeae6963dcfab62add15ac36417555 to your computer and use it in GitHub Desktop.
Service Worker loader and installer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if ('serviceWorker' in navigator) { | |
window.addEventListener('load', function() { | |
navigator.serviceWorker.register('/service-worker.js').catch(function(e) { | |
console.error('Error during service worker registration:', e); | |
}); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const version = 'v1'; | |
self.addEventListener('install', event => { | |
event.waitUntil( | |
caches.open(version).then(cache => { | |
return cache.addAll(['/offline', '/images/network-error.svg']); | |
}) | |
); | |
}); | |
self.addEventListener('fetch', event => { | |
if (!isCacheable(event.request)) { | |
return; | |
} | |
switch (event.request.destination) { | |
case 'style': | |
case 'script': | |
case 'image': | |
case 'font': | |
event.respondWith(firstCacheThenNetwork(event.request, 'asset')); | |
break; | |
default: | |
event.respondWith(firstNetworkThenCache(event.request, 'page')); | |
break; | |
} | |
}); | |
function isCacheable(request) { | |
return (request.method === 'GET') | |
&& (request.headers.get('X-Requested-With') !== 'XMLHttpRequest') | |
&& !request.url.match(/images\/large/); | |
} | |
function firstCacheThenNetwork(request, type) { | |
return caches.match(request).then(cached => { | |
const networked = fetch(request).then(response => { | |
return store(request, response, type); | |
}).catch(() => { | |
return; | |
}); | |
return cached || networked; | |
}); | |
} | |
function firstNetworkThenCache(request, type) { | |
return fetch(request).then(response => { | |
return store(request, response, type); | |
}).catch(e => { | |
return caches.match(request).then(cached => { | |
return cached ? cached : error(request, e); | |
}); | |
}); | |
} | |
function store(request, response, type) { | |
if (!response || (response.status !== 200)) { | |
return response; | |
} | |
return caches.open(version + '/' + type).then(cache => { | |
return cache.put(request, response.clone()).then(() => { | |
return response; | |
}); | |
}); | |
} | |
function error(request, e) { | |
switch (request.destination) { | |
case 'style': | |
return errorStyle(); | |
case 'script': | |
return errorScript(); | |
case 'image': | |
return errorImage(); | |
case 'font': | |
return errorFont(); | |
default: | |
return errorPage(); | |
} | |
} | |
function errorStyle() { | |
return setResponse('', 'text/css'); | |
} | |
function errorScript() { | |
return setResponse('', 'application/javascript'); | |
} | |
function errorImage() { | |
return caches.match('/images/network-error.svg').then(cached => { | |
return cached ? cached : setResponse('', 'image/svg+xml'); | |
}); | |
} | |
function errorFont() { | |
return setResponse('', 'application/font-woff2'); | |
} | |
function errorPage() { | |
return caches.match('/offline').then(cached => { | |
return cached ? cached : setResponse('D\'oh!, no connection :(', 'text/html'); | |
}); | |
} | |
function setResponse(message, contentType) { | |
return new Response(message, { | |
status: 503, | |
statusText: 'Service Unavailable', | |
headers: { 'Content-Type': contentType } | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment