Files
2nd/10_Wiki/Topics/Other/Progressive_Web_Apps_PWAs.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

6.9 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-progressive-web-apps-pwas Progressive Web Apps (PWAs) 10_Wiki/Topics verified self
PWA
Installable Web Apps
Web App Manifest Apps
none A 0.9 applied
web
frontend
mobile
service-worker
offline-first
2026-05-10 pending
language framework
javascript web-platform

Progressive Web Apps (PWAs)

매 한 줄

"매 the web with installability, offline, and push — without the app store tax.". 매 Alex Russell 이 2015년 정립한 PWA 는 매 service worker + manifest + HTTPS 의 조합으로 매 web app 을 매 native-feel 으로 격상. 매 2026: iOS 17+/Safari 17+ 가 push notifications 와 매 home-screen install 을 정식 지원, 매 Project Fugu API 들 (file system, USB, Bluetooth) 까지 가능.

매 핵심

매 3 pillars

  • Service Worker: 매 background script — 매 caching, 매 offline, 매 push.
  • Web App Manifest: 매 JSON — 매 install metadata (icon, name, display).
  • HTTPS: 매 mandatory transport (loopback exception for dev).

매 capabilities (2026)

  • 매 offline first via Cache + IndexedDB.
  • 매 background sync (eventual consistency).
  • 매 push notifications (iOS 17+ supports).
  • 매 file system access (Origin Private File System, OPFS).
  • 매 share target (receive shares from native).
  • 매 periodic background sync.
  • 매 WebGPU / WebTransport / WebCodecs.

매 응용

  1. Twitter, Pinterest, Starbucks Lite — 매 60-80% bundle reduction.
  2. 매 conference apps — 매 offline schedule + push.
  3. 매 internal enterprise tools — 매 install via QR, no MDM.
  4. 매 emerging-market apps — 매 low-bandwidth-friendly.

💻 패턴

Pattern 1: Minimal manifest.json

{
  "name": "Wiki Cleanup Tool",
  "short_name": "WikiClean",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#0066cc",
  "icons": [
    { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }
  ]
}

Pattern 2: Service worker (cache-first for assets, network-first for API)

// sw.js
const CACHE = 'app-v3';
const ASSETS = ['/', '/index.html', '/app.js', '/styles.css'];

self.addEventListener('install', (e) => {
  e.waitUntil(caches.open(CACHE).then((c) => c.addAll(ASSETS)));
});

self.addEventListener('activate', (e) => {
  e.waitUntil(caches.keys().then((keys) =>
    Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k)))
  ));
});

self.addEventListener('fetch', (e) => {
  const url = new URL(e.request.url);
  if (url.pathname.startsWith('/api/')) {
    // network-first
    e.respondWith(fetch(e.request).catch(() => caches.match(e.request)));
  } else {
    // cache-first
    e.respondWith(caches.match(e.request).then((r) => r || fetch(e.request)));
  }
});

Pattern 3: Registration with update flow

// app.js
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js').then((reg) => {
    reg.addEventListener('updatefound', () => {
      const sw = reg.installing;
      sw.addEventListener('statechange', () => {
        if (sw.state === 'installed' && navigator.serviceWorker.controller) {
          showUpdateToast(() => sw.postMessage({ type: 'SKIP_WAITING' }));
        }
      });
    });
  });
}

Pattern 4: Push notifications (2026 cross-platform)

async function subscribe() {
  const reg = await navigator.serviceWorker.ready;
  const sub = await reg.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: VAPID_PUBLIC_KEY,
  });
  await fetch('/api/save-sub', { method: 'POST', body: JSON.stringify(sub) });
}

// sw.js
self.addEventListener('push', (e) => {
  const { title, body, url } = e.data.json();
  e.waitUntil(self.registration.showNotification(title, { body, data: { url } }));
});
self.addEventListener('notificationclick', (e) => {
  e.notification.close();
  e.waitUntil(clients.openWindow(e.notification.data.url));
});

Pattern 5: Background sync for offline writes

// queue write when offline
async function postWithSync(url, payload) {
  try {
    return await fetch(url, { method: 'POST', body: JSON.stringify(payload) });
  } catch {
    const reg = await navigator.serviceWorker.ready;
    await idbAdd('outbox', { url, payload });
    await reg.sync.register('flush-outbox');
  }
}

// sw.js
self.addEventListener('sync', (e) => {
  if (e.tag === 'flush-outbox') e.waitUntil(flushOutbox());
});

Pattern 6: File System Access (2026 Fugu)

async function saveDoc(content) {
  const handle = await window.showSaveFilePicker({
    types: [{ description: 'Markdown', accept: { 'text/markdown': ['.md'] } }],
  });
  const writable = await handle.createWritable();
  await writable.write(content);
  await writable.close();
}

Pattern 7: Install prompt UX

let deferred;
window.addEventListener('beforeinstallprompt', (e) => {
  e.preventDefault();
  deferred = e;
  showCustomInstallButton();
});

async function onInstallClick() {
  if (!deferred) return;
  deferred.prompt();
  const { outcome } = await deferred.userChoice;
  analytics.track('pwa_install', { outcome });
  deferred = null;
}

매 결정 기준

상황 Approach
매 content-heavy site PWA, no native
매 needs deep OS integration (BLE, NFC, telephony) Native + Capacitor / native shell
매 cross-platform productivity PWA with Fugu APIs
매 emerging-market reach PWA — 매 small bundle, offline
매 game (heavy GPU) Native or WebGPU PWA
매 enterprise behind SSO PWA — 매 no app store distribution

기본값: 매 start with PWA, 매 fall back to native shell only when blocked APIs needed.

🔗 Graph

🤖 LLM 활용

언제: 매 caching strategy design, 매 SW boilerplate, 매 update-flow patterns. 언제 X: 매 native-only API needs (full BLE stack, deep telephony) — 매 use Capacitor / native.

안티패턴

  • Cache-everything: 매 stale stale stale — 매 use versioned cache + activate cleanup.
  • No update flow: 매 user stuck on old SW forever.
  • HTTPS skipped in staging: 매 SW won't register — 매 broken parity.
  • Manifest without maskable icons: 매 ugly cropped icons on Android adaptive.
  • Push spam: 매 user opt-out + iOS revoke + reputation damage.

🧪 검증 / 중복

  • Verified (W3C Service Worker spec, Web App Manifest spec, web.dev/learn/pwa).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — 3 pillars, 7 패턴, 2026 Fugu/iOS push 반영