PWA开发指南

Web App Manifest (manifest.json)

{ "name": "我的应用", "short_name": "MyApp", "description": "一个渐进式 Web 应用", "start_url": "/", "scope": "/", "display": "standalone", "orientation": "portrait", "theme_color": "#6c63ff", "background_color": "#1c2035", "icons": [ { "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" }, { "src": "/icons/icon-maskable.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" } ] } <!-- 在 HTML head 中引用 --> <link rel="manifest" href="/manifest.json"> <meta name="theme-color" content="#6c63ff">

Service Worker 注册

if ('serviceWorker' in navigator) { window.addEventListener('load', async () => { try { const reg = await navigator.serviceWorker.register('/sw.js', { scope: '/' }); console.log('SW 已注册:', reg.scope); } catch (err) { console.error('SW 注册失败:', err); } }); }

缓存策略

// sw.js — 缓存优先(静态资源) self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then(cached => { return cached || fetch(event.request); }) ); }); // 网络优先(API 请求) self.addEventListener('fetch', (event) => { event.respondWith( fetch(event.request) .then(response => { const clone = response.clone(); caches.open('api-cache').then(cache => cache.put(event.request, clone)); return response; }) .catch(() => caches.match(event.request)) ); });

缓存策略参考

策略最适合新鲜度
缓存优先静态资源、字体、图片旧直到更新
网络优先API 数据、动态内容始终最新,降级到缓存
过期同时重新验证偶尔变化的页面快速 + 下次访问时刷新
仅缓存预缓存资源静态
仅网络实时数据、认证端点始终最新,无离线