PWA
Service Worker やマニフェストを活用し、Web 技術でオフライン対応やプッシュ通知などネイティブアプリに近い体験を提供するアプローチ
Webモバイル
PWA とは
PWA (Progressive Web App) は、Service Worker、Web App Manifest、HTTPS を組み合わせて、Web アプリケーションにネイティブアプリに近い体験を提供するアプローチである。Google が 2015 年に提唱し、オフライン対応、プッシュ通知、ホーム画面へのインストールなどを Web 技術だけで実現する。
アプリストアを経由せずにユーザーに配布でき、URL でシェアできる。更新もサーバー側のデプロイだけで完了し、ユーザーにアップデートを強制する必要がない。
PWA の 3 つの柱
| 技術 | 役割 | 具体的な機能 |
|---|---|---|
| Service Worker | バックグラウンド処理 | オフラインキャッシュ、プッシュ通知、バックグラウンド同期 |
| Web App Manifest | アプリのメタデータ | ホーム画面アイコン、スプラッシュスクリーン、表示モード |
| HTTPS | セキュアな通信 | Service Worker の動作要件 |
Service Worker によるオフライン対応
Service Worker はブラウザとネットワークの間に位置するプロキシで、リクエストをインターセプトしてキャッシュから応答できる。
// service-worker.ts
self.addEventListener('fetch', (event: FetchEvent) => {
event.respondWith(
caches.match(event.request).then(cached => {
// キャッシュがあればキャッシュから返す (オフライン対応)
// なければネットワークから取得してキャッシュに保存
return cached || fetch(event.request).then(response => {
const clone = response.clone();
caches.open('v1').then(cache => cache.put(event.request, clone));
return response;
});
})
);
});
Web App Manifest
{
"name": "IT 技書の森",
"short_name": "技書の森",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#2d5016",
"icons": [
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" }
]
}
display: "standalone" を設定すると、ブラウザの UI (アドレスバー、タブ) が非表示になり、ネイティブアプリのような見た目になる。
ネイティブアプリとの比較
| 観点 | PWA | ネイティブアプリ |
|---|---|---|
| 配布 | URL でアクセス、ストア不要 | App Store / Google Play |
| 更新 | サーバー側デプロイのみ | ストア審査 + ユーザーの更新 |
| オフライン | Service Worker でキャッシュ | ネイティブにサポート |
| プッシュ通知 | Web Push API (iOS は制限あり) | フルサポート |
| デバイス API | 制限あり (Bluetooth, NFC は一部) | フルアクセス |
| パフォーマンス | ブラウザエンジンに依存 | ネイティブコードで高速 |
PWA が適するケース
- コンテンツ中心のアプリ (ニュース、ブログ、EC)
- オフラインでも閲覧したいアプリ (ドキュメント、レシピ)
- アプリストアの審査を避けたい場合
- Web とモバイルで同一コードベースを使いたい場合
PWA が不向きなケース
- 高度なデバイス API が必要 (AR、高精度 GPS)
- ゲームなど高いグラフィックス性能が必要
- iOS でのプッシュ通知が必須 (制限がある)
CloudFront + S3 での PWA ホスティング
静的サイトとして S3 にデプロイし、CloudFront で配信する構成は PWA と相性が良い。Service Worker のキャッシュと CloudFront のキャッシュを組み合わせることで、高速な配信とオフライン対応を両立できる。
Service Worker のファイル (sw.js) は Cache-Control: no-cache を設定し、常に最新版を取得させる。他の静的アセットは長期キャッシュを設定する。
体系的に学ぶなら関連書籍を参照してほしい。