iOS添加至主屏幕的PWA缓存一日后失效问题排查
Hey there, let's dig into your PWA offline issue on iOS—this is a common gotcha, so let's break it down step by step!
First off, the short answer is yes—iOS has built-in cache cleanup behavior for installed PWAs. Here's what's happening:
- iOS automatically cleans up PWA-related caches (including those managed by your Service Worker) after roughly 24 hours of inactivity. If you don't open the app during that window, the system may purge cached resources and even terminate the Service Worker entirely.
- System resource constraints can also trigger earlier cleanup, but your 1-day timeline lines up perfectly with the standard 24-hour auto-expiry rule.
Looking at your code, there are a few key issues that are making this problem worse:
- Empty Precache List: Your
PRECACHE_URLSarray is empty. Precache is meant to store your app's core "shell" resources (likeindex.html, main JS/CSS files) during installation. Without these cached upfront, if iOS clears your runtime cache, there's nothing left to load offline. - No Fallback for Failed Requests: Your fetch handler only checks the cache, then tries the network—but if both fail (like when offline and cache is gone), there's no fallback response. That's exactly why Safari shows the "no internet" error.
- No Cache Expiration Controls: While iOS handles its own cleanup, your code doesn't manage runtime cache validity. This can lead to stale resources or make it harder for iOS to prioritize which caches to keep.
Let's adjust your Service Worker and add some safeguards:
1. Precache Your Core App Resources
First, fill your PRECACHE_URLS with the critical files your app needs to load. For a CRA app, this includes your entry HTML, main JS/CSS, and any essential assets:
const PRECACHE = "precache-v1"; const RUNTIME = "runtime-v2"; const PRECACHE_URLS = [ "/", "/index.html", "/static/js/main.xyz123.js", // Use your actual hashed filename "/static/css/main.abc789.css", "/offline.html" // Add an offline fallback page ];
Pro tip: If you're using CRA, consider using its built-in PWA tooling (instead of writing a custom Service Worker) — it automatically generates this precache list for you, avoiding manual filename errors.
2. Add Offline Fallback & Cache Validity Checks
Update your fetch handler to handle offline scenarios gracefully, and add basic cache expiration to keep resources fresh:
this.addEventListener("fetch", event => { // Skip non-GET requests (we don't want to cache POST/PUT etc.) if (event.request.method !== "GET") return; event.respondWith( caches.match(event.request).then(cachedResponse => { // Return valid cached responses (check for 7-day expiry) if (cachedResponse) { const cacheDate = new Date(cachedResponse.headers.get("date")); const sevenDaysLater = new Date(cacheDate.getTime() + 7 * 24 * 60 * 60 * 1000); if (new Date() < sevenDaysLater) { return cachedResponse; } // Delete expired cache to refresh on next load caches.delete(event.request); } // Try network, update cache if successful return fetch(event.request) .then(networkResponse => { if (networkResponse.ok) { caches.open(RUNTIME).then(cache => { cache.put(event.request, networkResponse.clone()); }); } return networkResponse; }) // Fallback to offline page if network fails .catch(() => caches.match("/offline.html")); }) ); });
3. Keep Your Service Worker Active
iOS terminates idle Service Workers quickly. To mitigate this:
- Add a simple "ping" from your app to the Service Worker whenever it's opened (e.g., send a postMessage on app mount).
- Avoid long gaps between app opens—if users open your PWA at least once every 24 hours, iOS is less likely to purge its cache.
4. Verify iOS PWA Requirements
Double-check that your app meets all iOS PWA installation criteria:
- Valid
manifest.jsonwithname,short_name,start_url, and appropriate icons/splash screens. - Served over HTTPS (required for Service Workers and PWA installation).
- Correct
apple-touch-iconandapple-mobile-web-app-capablemeta tags.
iOS's cache cleanup is a bit aggressive, but with proper precaching, fallback logic, and Service Worker management, you can keep your offline PWA working reliably. Using CRA's built-in PWA tools will save you a lot of headache with iOS-specific quirks!
内容的提问来源于stack exchange,提问作者Joey Hotz

