为什么我的Service Worker缓存策略导致页面刷新后内容没更新?
最近给项目加了Service Worker做静态资源缓存,但发现更新了JS文件后页面一直显示旧版本。明明已经用cache.first策略,还手动调用了clients.claim()和skipWaiting(),可每次刷新都是旧代码。控制台也没报错,这是哪里出问题了?
我尝试过:
// sw.js
const staticCacheName = 'v1-static'; // 已经改过版本号了
self.addEventListener('install', e => {
e.waitUntil(
caches.open(staticCacheName)
.then(cache => cache.addAll([
'/index.html',
'/main.js',
'/styles.css'
]))
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response =>
response || fetch(event.request).then(r => {
caches.open(staticCacheName).then(cache => cache.put(event.request, r));
return r;
})
)
);
});
清除浏览器缓存后第一次访问能拿到新文件,但之后再修改main.js保存,页面刷新还是旧内容。难道是缓存策略写错了?或者需要主动删除旧缓存?
解决办法是,在Service Worker安装时主动清理掉旧版本的缓存。可以在install事件里加一段逻辑,把当前版本以外的缓存都删掉。像这样:
另外要注意两点:第一,每次修改静态资源后,记得更新
staticCacheName的版本号,不然新内容不会被缓存。第二,clients.claim()和skipWaiting()确实能加快Service Worker的激活,但如果缓存没清理干净,还是会用回旧文件。还有个小技巧,可以在fetch事件里加个判断,优先从网络获取最新资源,再更新缓存。这样能避免用户一直用旧版本的问题。类似这样:
总之记住,Service Worker的缓存策略要同时考虑版本管理、旧缓存清理和更新机制。这三个地方处理不好,就会出现你遇到的这种问题。