必须在install阶段预缓存CSS,否则首次离线访问必然白屏或样式断裂;因CSS是渲染阻塞资源,HTML解析时同步等待其加载,若此时断网且缓存未提前就位,请求失败导致样式缺失。

必须在 install 阶段用 cache.addAll() 预缓存 CSS 文件,否则首次离线访问必然白屏或样式断裂——这不是缓存没写对,而是根本没让它“提前就位”。
为什么 install 阶段缓存 CSS 是硬性要求
CSS 是渲染阻塞资源:HTML 解析到 <link rel="stylesheet" href="styles.css"> 时,会同步发起请求并等待响应完成才继续渲染。如果此时断网,且 Service Worker 没在激活前就把 styles.css 存进缓存,这个请求就会失败,浏览器得不到任何 CSS 内容。
-
fetch事件中按需缓存(比如caches.match(event.request))只适用于非阻塞资源,对 CSS 来说太晚了 -
install阶段的cache.addAll()是原子操作:所有 URL 必须全部成功,否则整个 install 失败,不会留下半缓存状态 - 即使你只改了一行 CSS,也必须更新
CACHE_NAME,否则旧缓存永不淘汰,用户永远看不到新样式
cache.addAll() 中 CSS 路径写错的典型表现
控制台不报错,但 DevTools → Application → Cache Storage 里就是找不到 styles.css——因为 cache.addAll() 对路径极其敏感,静默失败是常态。
- 必须用绝对路径,和 HTML 中
<link href="">的值完全一致:比如 HTML 里是/css/main.css,就不能写成css/main.css或./css/main.css - 构建后路径可能变化:若用 Webpack/Vite 打包,CSS 被哈希重命名(如
main.a1b2c3.css),缓存列表里就得填最终产物名,不是源文件名 - 带查询参数的 URL(如
styles.css?v=2.1)会被当作独立键,后续请求必须含相同参数才能命中;不推荐,改CACHE_NAME更可靠
离线时 CSS 仍加载失败?检查这三个拦截点
缓存了 CSS 不等于它能被用上——Service Worker 还得在运行时把请求真正导向缓存。
立即学习“前端免费学习笔记(深入)”;
-
fetch事件必须监听并响应 CSS 请求:event.respondWith(caches.match(event.request).then(r => r || fetch(event.request))) - 建议加类型过滤,避免误伤其他请求:
if (event.request.destination === 'style')再走缓存逻辑 -
index.html本身也必须被cache.addAll()缓存,否则连 HTML 都打不开,CSS 根本没机会被请求
开发阶段 CSS 缓存总不生效?先确认协议和环境
90% 的“缓存无效”问题其实卡在启动方式上——file:// 协议下 Service Worker 完全不工作,这是浏览器强制限制。
- 本地测试必须起 HTTP 服务:用
python3 -m http.server、VS Code Live Server,或npx serve - 地址栏必须是
http://localhost:8000或https://开头,双击 HTML 打开的file:///页面永远注册失败 - 移动端调试时,确认页面 URL 不是
ionic://或capacitor://等自定义协议,它们对 SW 支持不一
真正让 PWA 离线可用的,从来不是“写了缓存代码”,而是每次发版后手动验证三件事:缓存名是否递增、CSS 路径是否与 HTML 一致、Cache Storage 里那个文件是否真实存在且大小非零。


















