零流量启动需用Service Worker预缓存核心资源并拦截请求,结合版本化manifest管理离线包、IndexedDB存储图片、内存+磁盘双层缓存优化读取速度。

移动端 H5 实现“零流量也能正常打开”,关键不是等用户断网才响应,而是提前把页面所需资源完整存到本地,并在加载时绕过网络直接读取。这需要一套分层、可控、可更新的离线策略,而不是依赖浏览器默认缓存或简单 localStorage。
用 Service Worker 拦截所有页面请求
Service Worker 是实现零流量启动的底层基础。它能作为网络代理,在页面发起任何请求(HTML、JS、CSS、图片、字体)前就介入:
- 注册后监听 install 和 fetch 事件,首次加载时预缓存核心资源(如 index.html、app.js、style.css、logo.png)
- 后续每次访问,fetch 事件会先查 Cache Storage;命中则直接返回缓存 Response,不发网络请求
- 对非关键资源(如轮播图、广告位)可设为“网络优先+失败 fallback 到缓存”,避免阻塞首屏
- 注意:SW 只对 HTTPS 或 localhost 生效,且需确保主页面本身能被缓存(不能是 no-cache 或动态生成)
资源打包 + 版本化清单管理
光靠 runtime 缓存不可靠,尤其面对更新和清理。推荐采用“离线包”模式,把整页静态资源压缩打包,配合 manifest.json 管理:
- manifest.json 包含版本号、每个文件路径与 hash 值,用于校验完整性
- 首次加载时下载 zip 包 → 解压 → 存入 IndexedDB 或 FileSystem API(iOS Safari 16.4+ 支持)
- 后续访问通过 manifest 对比版本,仅下载变更文件(增量更新),节省流量和存储
- 页面 JS 加载逻辑中,不再用传统 src/href,而是调用本地资源读取方法(如 readFromCache('/index.html'))
图片等二进制资源单独优化存储
响应式图片(srcset / picture)在离线时容易失效,因为浏览器仍会按设备特征发出多个 URL 请求。必须主动接管:
- 不用 base64 存 localStorage(膨胀大、性能差),改用 IndexedDB 直接存 Blob 或 ArrayBuffer
- 缓存键设计为 “原始 URL + dpr + format”,例如 https://cdn.com/icon.png#dpr=2&format=webp
- JS 加载前检测 window.devicePixelRatio 和 canvas.toDataURL('image/webp'),再决定查哪个键
- 离线时未命中则 fallback 到 1x jpg,保证基本可用性
内存 + 磁盘双层缓存提升冷启速度
纯磁盘读取有 IO 延迟,尤其低端安卓机。可叠加轻量级内存缓存:
- 页面加载时,将已读取的 HTML/JS/CSS 字符串暂存在全局 Map 或 WeakMap 中
- 同一 session 内再次访问同页面,优先从内存取,毫秒级返回
- 内存缓存设 TTL(如 5 分钟)或最大条目数,避免内存泄漏
- 磁盘缓存(IndexedDB)作为持久底座,兜底跨 session 场景


















