缓存 css 必须显式拦截:service worker 不会自动缓存 link 标签加载的样式,需在 install 或 fetch 阶段用 event.request.destination === 'style' 判断并调用 cache.put();务必检查 response.status === 200 和 mime 类型,响应前需 clone();@import 和 url() 资源需单独预缓存;更新 css 时须在 activate 中清理旧缓存。

缓存 CSS 必须显式拦截,浏览器不会自动帮你存
Service Worker 不会自动把 <link rel="stylesheet"> 加载的 CSS 丢进缓存——哪怕你已经注册了 SW,CSS 仍走网络。你得在 install 或 fetch 阶段主动写逻辑抓它。
常见错误是只监听 fetch 却没加判断条件,结果把 API、图片甚至 302 响应全塞进缓存,导致后续返回错内容或缓存膨胀。
- 用
event.request.destination === 'style'判断最可靠(比url.endsWith('.css')强得多,能避开 query 参数、CDN 路径变形等坑) -
install阶段适合预缓存已知关键 CSS(如main.css),路径必须和 HTML 中<link href="...">的值完全一致(包括斜杠、大小写、?v=1.2) -
fetch阶段适合处理动态加载的 CSS(比如组件级样式),但要显式调用cache.put()或cache.addAll()
缓存前必须检查响应状态和类型
直接 cache.put(req, response) 很危险:404、500、重定向响应都会被原样存下,下次离线时用户就看到白屏或错样式。
- 务必加
if (response.status === 200)过滤,否则缓存失效风险极高 - CSS 必须返回
text/cssMIME 类型;有些 CDN 会省略或写成text/plain,别依赖response.headers.get('Content-Type')判断,还是以request.destination为准 - 存之前一定要
response.clone():Response 流只能读一次,不 clone 就会导致 fetch 后续无法读取 body
@import 和 url() 里的资源不会被自动拦截
只缓存了 main.css,但它里面写了 @import "theme.css"?那 theme.css 依然走网络,离线时直接失效。
-
@import是 CSS 解析器内部发起的请求,不经过 Service Worker 的fetch事件 -
background: url(./img.png)、@font-face src: url(...)同理,不会被当前 SW 拦截 - 解决办法只有两个:把
@import拆成多个<link>标签,或用构建工具(如 PostCSS)提前内联;url()资源需单独列进urlsToCache数组
缓存更新 ≠ Service Worker 更新,旧 CSS 会一直留在 Cache Storage 里
改了 CSS 文件、也更新了 service-worker.js 并重新注册,用户刷新页面后还是看不到新样式——因为旧缓存没清,SW 仍在用老版本的 cache 实例。
- 激活新 SW 时,必须在
activate事件里显式清理旧缓存:caches.delete(cacheName),不能只靠换CACHE_NAME变量名 - 推荐用带语义的缓存名,比如
'css-v202607',并在activate中删掉所有不匹配该前缀的 cache - 开发阶段可调用
navigator.serviceWorker.getRegistration().then(r => r?.update())强制检查更新;上线后建议配合skipWaiting()(前提是 CSS 更改向后兼容)
from cache 才算成功,from ServiceWorker 只代表请求被拦截了,不代表缓存命中。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











