Created
October 27, 2018 20:21
-
-
Save JMPerez/8ca8d5ffcc0cc45a8b4e1c279efd8a94 to your computer and use it in GitHub Desktop.
An example of a service worker for serving network first, cache second
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
// the cache version gets updated every time there is a new deployment | |
const CACHE_VERSION = 10; | |
const CURRENT_CACHE = `main-${CACHE_VERSION}`; | |
// these are the routes we are going to cache for offline support | |
const cacheFiles = ['/', '/about-me/', '/projects/', '/offline/']; | |
// on activation we clean up the previously registered service workers | |
self.addEventListener('activate', evt => | |
evt.waitUntil( | |
caches.keys().then(cacheNames => { | |
return Promise.all( | |
cacheNames.map(cacheName => { | |
if (cacheName !== CURRENT_CACHE) { | |
return caches.delete(cacheName); | |
} | |
}) | |
); | |
}) | |
) | |
); | |
// on install we download the routes we want to cache for offline | |
self.addEventListener('install', evt => | |
evt.waitUntil( | |
caches.open(CURRENT_CACHE).then(cache => { | |
return cache.addAll(cacheFiles); | |
}) | |
) | |
); | |
// fetch the resource from the network | |
const fromNetwork = (request, timeout) => | |
new Promise((fulfill, reject) => { | |
const timeoutId = setTimeout(reject, timeout); | |
fetch(request).then(response => { | |
clearTimeout(timeoutId); | |
fulfill(response); | |
update(request); | |
}, reject); | |
}); | |
// fetch the resource from the browser cache | |
const fromCache = request => | |
caches | |
.open(CURRENT_CACHE) | |
.then(cache => | |
cache | |
.match(request) | |
.then(matching => matching || cache.match('/offline/')) | |
); | |
// cache the current page to make it available for offline | |
const update = request => | |
caches | |
.open(CURRENT_CACHE) | |
.then(cache => | |
fetch(request).then(response => cache.put(request, response)) | |
); | |
// general strategy when making a request (eg if online try to fetch it | |
// from the network with a timeout, if something fails serve from cache) | |
self.addEventListener('fetch', evt => { | |
evt.respondWith( | |
fromNetwork(evt.request, 10000).catch(() => fromCache(evt.request)) | |
); | |
evt.waitUntil(update(evt.request)); | |
}); |
where do i register my service worker? i am currently using creact react app
Thanks , its worked !!!!
This is such a great service worker implementation. Thanx for that.
I understand, this is a very basic service worker. But I will point out two things for others to understand before using it.
- This will not distinguish cross-origin requests (i.e., google analytics, google maps, other api, etc). It will try to cash that.
- In case of POST it will fail and rightly so but it should be handled properly. Meaning, the POST requests should be avoided caching.
The default caching behavior of my P.W.A. had completely smothered my ability to update a line of code! This network-first implementation is exactly what I needed. "It feels like I'm caching nohtin' at all!"
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Wooooooow, what a nice SW!!!! Thanks a lot!