Service Worker 更新后需在activate事件中手动清理旧缓存,因该阶段旧Worker已停用、新Worker未接管请求,可安全删除过期缓存;标准做法是用caches.keys()获取全部缓存名,filter筛选非当前版本缓存,再用Promise.all(caches.delete())并行清除。

在 Service Worker 更新后,旧版本的缓存不会自动删除,必须在新 Service Worker 的 activate 事件中手动清理。这是避免缓存污染、确保资源更新生效的关键步骤。
为什么要在 activate 阶段清理缓存
activate 是新 Service Worker 取代旧版的临界点:此时旧 Worker 已停止控制页面,新 Worker 已安装完成但尚未接管请求。只有这时才能安全删除旧缓存——既不会中断当前页面加载(旧缓存仍在用),也不会影响新缓存的初始化。
清理过期缓存的标准写法
核心逻辑是:获取所有已命名的缓存列表 → 过滤出「当前不需保留」的缓存名 → 调用 caches.delete() 逐个删除。
- 提前定义好当前版本使用的缓存名(如
CACHE_NAME = 'v2-static') - 在
activate回调中使用caches.keys()获取全部缓存名 - 用
.filter()筛出非当前缓存名(例如包含'v1'或不匹配正则/^v\d+-/的) - 对每个待删缓存名执行
caches.delete(name),建议用Promise.all()并行处理
完整示例代码
(假设当前使用 v3-static 和 v3-dynamic)
const CURRENT_CACHES = {
static: 'v3-static',
dynamic: 'v3-dynamic'
};
self.addEventListener('activate', event => {
const cacheWhitelist = Object.values(CURRENT_CACHES);
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (!cacheWhitelist.includes(cacheName)) {
return caches.delete(cacheName);
}
})
);
})
);
});
注意事项和常见坑
- 务必调用
event.waitUntil(),否则浏览器可能在清理完成前终止 Worker - 不要在
install或fetch中删缓存——install时旧缓存还在用,fetch中删可能引发竞态 - 如果使用了
CacheStorage.match()或自定义缓存策略,确保清理逻辑覆盖所有可能的缓存名变体(如带时间戳或哈希的命名) - 开发阶段可加
console.log输出被删的缓存名,上线前移除










