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 產生的概覽

提供建置漸進式網頁應用程式的指引與程式碼模式,涵蓋 Service Worker、快取、離線支援與可安裝性。

功能
此技能提供漸進式網頁應用程式開發的參考指引,涵蓋網頁應用程式資訊清單設定、Service Worker 註冊與生命週期,以及快取優先、網路優先、先回傳舊內容再重新驗證等快取策略。它也說明了背景同步、推播通知、離線偵測、效能最佳化、測試與最佳實務。產出為說明文字與範例程式碼片段,而非產生的檔案或可執行的工具。
適用情境
適用於實作或審查需要離線優先行為、可安裝性或 Service Worker 快取的網頁應用程式。也適合回答資訊清單設定、背景同步、推播通知或 PWA 稽核相關問題。
執行需求
此技能未附帶指令碼或資源,僅為指示性內容。依其範例操作需要以 HTTPS 提供的網頁專案、支援 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 從公開儲存庫中收錄這些內容。

檢舉或申請下架