iOS端service worker缓存异常导致Firestore数据加载极慢问题求助
核心原因
iOS WebKit对Service Worker的生命周期、请求调度逻辑和其他平台实现存在差异,你的触发逻辑和拦截规则刚好触发了WebKit的调度bug:
navigator.serviceWorker.register的回调仅代表注册流程完成,不代表install阶段的cache.addAll资源缓存完成,你提前跳转后,仍在运行的缓存任务会抢占WebKit的网络请求配额,Firestore的动态请求会被推入低优先级队列等待。- 你当前的fetch拦截逻辑会处理所有请求,包括Firestore的动态API/长连接请求,WebKit对被Service Worker拦截的非缓存跨域请求存在额外的调度延迟,极端情况会等到Service Worker后台任务超时后才放行请求,就是你遇到的20分钟延迟的情况。
修复方案
1. 调整跳转时机,等Service Worker完全激活后再跳转
修改Index.html中的注册逻辑:
if('serviceWorker' in navigator) { navigator.serviceWorker .register('/sw.js') .then(function(registration) { console.log("Service Worker Registered"); // 监听SW安装状态,完全激活后再跳转 const checkState = () => { if (registration.active) { window.location = "/trasy.html"; return; } const worker = registration.installing || registration.waiting; if (worker) { worker.addEventListener('statechange', checkState); } }; checkState(); }); }
2. 过滤动态请求,不交由Service Worker缓存处理
修改sw.js的fetch事件逻辑,跳过Firebase相关的动态请求:
self.addEventListener('fetch', function(event) { const requestUrl = new URL(event.request.url); // 所有Firebase相关的动态请求直接走网络,不经过缓存逻辑 if (requestUrl.hostname.includes('firebase') || requestUrl.hostname.includes('firestore.googleapis.com')) { event.respondWith(fetch(event.request)); return; } // 仅静态资源走缓存优先逻辑 event.respondWith( caches.match(event.request).then(function(response) { return response || fetch(event.request); }) ); });
3. 可选优化:加速Service Worker接管
在sw.js的install和activate事件中添加以下逻辑,避免旧SW残留:
self.addEventListener('install', (e) => { e.waitUntil( caches.open('airhorner').then(function(cache) { return cache.addAll([ "/trasy.html", "/styles/all.css", "/styles/trasy.css", "/scripts/firebaseInit.js", "/scripts/trasy.js" ]); }).then(() => self.skipWaiting()) // 安装完成后跳过等待直接激活 ); }); self.addEventListener('activate', (e) => { e.waitUntil(clients.claim()); // 激活后立刻接管所有打开的页面 });
排查验证方法
在Mac端打开Safari的开发者模式,通过 lightning 线连接iOS设备,选择iOS设备上对应页面的Web检查器,查看网络面板中Firestore请求的状态、时间线,以及Service Worker的控制台日志,确认请求是否已经绕过缓存逻辑正常触发。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

