Service Worker 的缓存优先策略是先查缓存命中即返回、未命中再发网络请求,通过 fetch 事件中调用 caches.match() 实现,适用于 CSS、JS、字体、图标等静态资源,但不适用于主 HTML 入口文件。

Service Worker 的缓存优先读取策略,核心是让浏览器**先查缓存、命中就直接返回,未命中再走网络**。这不是靠 HTTP 头控制,而是通过 fetch 事件中调用 caches.match() 主动判断并响应。
缓存优先(Cache-First)适用哪些资源
这类策略适合内容稳定、靠文件名哈希区分版本的静态资源:
- CSS、JavaScript 文件(如
app.a3f2.js、styles.b8e1.css) - 字体文件(
.woff2)、图标、Logo 等图片 - 预缓存的 HTML 模板(非入口 HTML,比如组件模板)
⚠️ 注意:不要对主 HTML 入口文件(如 /index.html)直接用 Cache-First,否则新版本永远无法加载。
基础实现代码(缓存优先)
在 Service Worker 的 fetch 事件中写入以下逻辑:
立即学习“Java免费学习笔记(深入)”;
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
// 缓存存在,直接返回
if (response) return response;
// 缓存不存在,发起网络请求
return fetch(event.request);
})
);
});
这段代码简洁有效,但需注意两个关键点:
-
请求匹配严格:
caches.match()要求 URL 完全一致(含 query 参数),/data.json和/data.json?t=123视为不同请求; -
响应可被缓存的前提:只有
GET请求且响应状态码为 200、206、304 才会被cache.addAll()或cache.put()正确存入。
配合安装阶段预缓存,确保“有得可读”
光有 fetch 拦截不够,得先让资源进缓存。在 install 阶段预加载核心静态资源:
const CACHE_NAME = 'static-v1';
const urlsToCache = [
'/styles/main.css',
'/scripts/app.js',
'/fonts/inter.woff2',
'/images/logo.svg'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(urlsToCache))
);
});
这样用户首次访问时,关键资源已就位,后续请求就能真正“优先读取”。
进阶:自动更新缓存,避免旧资源滞留
缓存优先容易导致“永远不更新”。推荐在 fetch 中加一层后台刷新逻辑(Stale-While-Revalidate 变体):
- 先返回缓存响应(保证速度);
- 同时用
fetch()获取新资源,并用cache.put()更新缓存(不影响本次响应); - 下一次请求自然拿到新内容。
示例片段:
self.addEventListener('fetch', event => {
const request = event.request;
event.respondWith(
caches.match(request).then(cached => {
const networkFetch = fetch(request).then(response => {
if (response.status === 200) {
return caches.open(CACHE_NAME).then(cache => {
cache.put(request, response.clone());
return response;
});
}
});
return cached || networkFetch;
})
);
});
这种写法兼顾了首屏速度与内容新鲜度,特别适合 App Shell 或静态页面外壳。


















