Pwa Development

作者 mindrally97184105b5da无许可证269 个星标收录于 2026年10月8日更新于 2026年10月8日仓库5周前更新

Progressive Web App development guidelines covering service workers, caching strategies, offline functionality, and installability

AI 生成的概览

提供构建渐进式 Web 应用的指南与代码模式,涵盖 Service Worker、缓存、离线支持与可安装性。

功能
该技能提供渐进式 Web 应用开发的参考指南,涵盖 Web 应用清单配置、Service Worker 注册与生命周期,以及缓存优先、网络优先、陈旧内容先返回再验证等缓存策略。它还说明了后台同步、推送通知、离线检测、性能优化、测试与最佳实践。产出为说明性文字与示例代码片段,而非生成的文件或可运行工具。
适用场景
适用于实现或审查需要离线优先行为、可安装性或 Service Worker 缓存的 Web 应用。也适合解答清单配置、后台同步、推送通知或 PWA 审计相关问题。
运行要求
该技能不附带脚本或资源,仅为说明性指令。按其示例操作需要以 HTTPS 提供的 Web 项目、支持 Service Worker 的浏览器,推送通知还需 VAPID 密钥对与服务端接口。

Progressive Web App Development Guidelines

You are an expert in building Progressive Web Applications with offline-first capabilities.

Core Principles

  • Design for offline-first experience
  • Implement proper caching strategies
  • Ensure fast loading and smooth performance
  • Follow web app manifest best practices
  • Provide native-like experience

Web App Manifest

json
{  "name": "My Progressive Web App",  "short_name": "MyPWA",  "description": "A description of your app",  "start_url": "/",  "display": "standalone",  "background_color": "#ffffff",  "theme_color": "#000000",  "icons": [    {      "src": "/icons/icon-192.png",      "sizes": "192x192",      "type": "image/png"    },    {      "src": "/icons/icon-512.png",      "sizes": "512x512",      "type": "image/png"    }  ]}

Service Worker Registration

javascript
// Register service workerif ('serviceWorker' in navigator) {  window.addEventListener('load', async () => {    try {      const registration = await navigator.serviceWorker.register('/sw.js');      console.log('SW registered:', registration.scope);    } catch (error) {      console.error('SW registration failed:', error);    }  });}

Service Worker Implementation

javascript
// sw.jsconst CACHE_NAME = 'v1';const STATIC_ASSETS = [  '/',  '/index.html',  '/styles.css',  '/app.js',  '/offline.html'];
// Install event - cache static assetsself.addEventListener('install', (event) => {  event.waitUntil(    caches.open(CACHE_NAME).then((cache) => {      return cache.addAll(STATIC_ASSETS);    })  );  self.skipWaiting();});
// Activate event - cleanup old cachesself.addEventListener('activate', (event) => {  event.waitUntil(    caches.keys().then((cacheNames) => {      return Promise.all(        cacheNames          .filter((name) => name !== CACHE_NAME)          .map((name) => caches.delete(name))      );    })  );  self.clients.claim();});
// Fetch event - serve from cache or networkself.addEventListener('fetch', (event) => {  event.respondWith(    caches.match(event.request).then((response) => {      return response || fetch(event.request);    }).catch(() => {      return caches.match('/offline.html');    })  );});

Caching Strategies

Cache First (Static Assets)

javascript
async function cacheFirst(request) {  const cached = await caches.match(request);  return cached || fetch(request);}

Network First (Dynamic Content)

javascript
async function networkFirst(request) {  try {    const response = await fetch(request);    const cache = await caches.open(CACHE_NAME);    cache.put(request, response.clone());    return response;  } catch {    return caches.match(request);  }}

Stale While Revalidate

javascript
async function staleWhileRevalidate(request) {  const cache = await caches.open(CACHE_NAME);  const cached = await cache.match(request);
  const fetchPromise = fetch(request).then((response) => {    cache.put(request, response.clone());    return response;  });
  return cached || fetchPromise;}

Background Sync

javascript
// Register sync in main appasync function registerSync() {  const registration = await navigator.serviceWorker.ready;  await registration.sync.register('sync-data');}
// Handle sync in service workerself.addEventListener('sync', (event) => {  if (event.tag === 'sync-data') {    event.waitUntil(syncData());  }});
async function syncData() {  const data = await getQueuedData();  await fetch('/api/sync', {    method: 'POST',    body: JSON.stringify(data)  });}

Push Notifications

javascript
// Request permissionasync function requestNotificationPermission() {  const permission = await Notification.requestPermission();  if (permission === 'granted') {    const registration = await navigator.serviceWorker.ready;    const subscription = await registration.pushManager.subscribe({      userVisibleOnly: true,      applicationServerKey: PUBLIC_VAPID_KEY    });    // Send subscription to server  }}
// Handle push in service workerself.addEventListener('push', (event) => {  const data = event.data.json();  event.waitUntil(    self.registration.showNotification(data.title, {      body: data.body,      icon: '/icons/icon-192.png'    })  );});

Offline Detection

javascript
// Check online statuswindow.addEventListener('online', () => {  console.log('Back online');  syncPendingData();});
window.addEventListener('offline', () => {  console.log('Offline mode');  showOfflineIndicator();});

Performance Optimization

  • Implement app shell architecture
  • Use lazy loading for routes and components
  • Optimize images with responsive formats
  • Minimize JavaScript bundle size
  • Use code splitting

Testing

  • Test offline functionality
  • Verify caching behavior
  • Test on various network conditions
  • Validate manifest and icons
  • Use Lighthouse for PWA audits

Best Practices

  • Serve over HTTPS
  • Provide meaningful offline experience
  • Handle service worker updates gracefully
  • Implement proper error handling
  • Add loading states and skeletons

来源与署名

来源:mindrally/skills位于pwa-development提交9718410

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架