必须预获取的svg仅三类:核心导航图标、框架级svg sprite文件、路径固定的静态图标;其他如带版本号或动态生成的路径应按需缓存。

明确哪些SVG必须预获取
不是所有SVG都适合在页面加载前就拉取。真正需要预获取的只有三类:
- 核心导航图标:比如 logo.svg、menu.svg、close.svg,首次渲染就依赖,缺了会破坏基础交互
- 框架级 SVG Sprite 文件:如 icons-sprite.svg 或 Lucide/Feather 的整包资源,它们是图标系统的“主干”,必须一次性载入
- 路径固定的静态图标:存放在 /icons/ 下、无查询参数、无哈希后缀的文件(例如 /icons/home.svg),这类路径稳定,匹配可靠
带 ?v=1.2.3、-abc123.svg 后缀,或由 JS 拼接生成的路径,不适合预获取——更适合运行时按需缓存 + ignoreSearch 匹配。
URL匹配必须严格可控
caches.match() 默认逐字符比对完整 URL,协议、大小写、查询参数全算在内。一个常见失效场景是:HTML 请求 /icons/user.svg?v=2,但缓存里只存了 /icons/user.svg;或者缓存了 /Icons/user.svg(大写 I),而引用路径是小写。
解决办法分两层:
- 构建阶段统一路径规范:禁用自动加版本号,或在 cache.addAll() 列表中显式带上一致的查询参数
- 运行时匹配放宽条件:使用 caches.match(request, { ignoreSearch: true })
- 确保拦截范围覆盖全面:fetch 事件中判断 request.destination === 'image' || request.destination === 'document',既抓 SVG 文件,也抓内联了 SVG 的 HTML 页面
缓存交付不能有空档
Service Worker 的 fetch 事件一旦触发,就必须立刻调用 event.respondWith()。浏览器对响应有超时限制,如果只在部分分支里调用,或延迟执行,未命中的请求就会回退到网络——离线能力直接失效。
关键操作原则:
- 首行即调用 respondWith,哪怕只是返回 fallback 响应
- 避免在异步逻辑(如 await fetch)之后才调用,容易超时
- 更新缓存时同步升级 CACHE_NAME,并在 activate 阶段主动清理旧缓存,防止残留干扰
多层缓存协同更稳
单靠 Service Worker 预缓存不够稳健。建议叠加其他层级:
- HTTP 缓存:Nginx 配置 SVG 的 Cache-Control: public, max-age=31536000,利用浏览器原生缓存
- 内存缓存:前端框架(如 React)可对已解析的 SVG 字符串做轻量级 Map 缓存,避免重复 DOM 解析
- 磁盘缓存:移动端 WebView 或 RN 环境中,借助 Glide、SVGKit 等库的内置磁盘缓存机制,复用已下载的原始数据
预获取负责“首次必快”,多层缓存负责“后续更稳”,两者配合才能真正实现秒级加载与离线可用。











