Skip to content

Instantly share code, notes, and snippets.

@AimWhy
Forked from fibo/cache.js
Created October 23, 2022 07:08
Show Gist options
  • Select an option

  • Save AimWhy/6ea996fccd06864dac976a604158666e to your computer and use it in GitHub Desktop.

Select an option

Save AimWhy/6ea996fccd06864dac976a604158666e to your computer and use it in GitHub Desktop.
Service Worker implementing stale-while-revalidate caching strategy.
/* global caches, fetch, self */
// Fill here with your cache name-version.
const CACHE_NAME = 'my-cache-v1'
// This is the list of URLs to be cached by your Progressive Web App.
const CACHED_URLS = [
'/',
'/bundle.js',
'/manifest.json',
'/register.js',
'/media/myapp-192x192.png',
'/media/myapp-512x512.png'
]
// Open cache on install.
self.addEventListener('install', event => {
event.waitUntil(async function () {
const cache = await caches.open(CACHE_NAME)
await cache.addAll(CACHED_URLS)
}())
})
// Cache and update with stale-while-revalidate policy.
self.addEventListener('fetch', event => {
const { request } = event
// Prevent Chrome Developer Tools error:
// Failed to execute 'fetch' on 'ServiceWorkerGlobalScope': 'only-if-cached' can be set only with 'same-origin' mode
//
// See also https://stackoverflow.com/a/49719964/1217468
if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
return
}
event.respondWith(async function () {
const cache = await caches.open(CACHE_NAME)
const cachedResponsePromise = await cache.match(request)
const networkResponsePromise = fetch(request)
if (request.url.startsWith(self.location.origin)) {
event.waitUntil(async function () {
const networkResponse = await networkResponsePromise
await cache.put(request, networkResponse.clone())
}())
}
return cachedResponsePromise || networkResponsePromise
}())
})
// Clean up caches other than current.
self.addEventListener('activate', event => {
event.waitUntil(async function () {
const cacheNames = await caches.keys()
await Promise.all(
cacheNames.filter((cacheName) => {
const deleteThisCache = cacheName !== CACHE_NAME
return deleteThisCache
}).map(cacheName => caches.delete(cacheName))
)
}())
})
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator
.serviceWorker
.register('cache.js', { scope: '/' })
.then(registration => {
console.log('ServiceWorker registration')
}, err => {
console.error('ServiceWorker registration failed', err)
})
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment