注册与基础:// main.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
}
缓存策略实现:// sw.js
const STATIC = 'static-v1'
self.addEventListener('install', (e) => {
e.waitUntil(caches.open(STATIC).then((c) => c.addAll(['/','/app.css','/app.js'])))
})
self.addEventListener('activate', (e) => {
e.waitUntil(caches.keys().then((keys) => Promise.all(keys.filter(k=>k!==STATIC).map(k=>caches.delete(k)))))
})
// Cache First
async function cacheFirst(req) {
const cached = await caches.match(req)
if (cached) return cached
const resp = await fetch(req)
const cache = await caches.open(STATIC)
cache.put(req, resp.clone())
return resp
}
// Network First
async function networkFirst(req) {
try {
const resp = await fetch(req)
const cache = await caches.open(STATIC)
cache.put(req, resp.clone())
return resp
} catch {
return caches.match(req)
}
}
// Stale-While-Revalidate
async function swr(req) {
const cached = await caches.match(req)
const fetchPromise = fetch(req).then((resp) => caches.open(STATIC).then((c) => c.put(req, resp.clone())).then(() => resp))
return cached || fetchPromise
}
self.addEventListener('fetch', (e) => {
const { request } = e
if (request.destination === 'document') e.respondWith(networkFirst(request))
else if (request.destination === 'script' || request.destination === 'style') e.respondWith(cacheFirst(request))
else e.respondWith(swr(request))
})

发表评论 取消回复