Service Worker(オフライン対応)
serviceWorker.register cache fetch イベント
Service WorkerはWebページとネットワークの間に位置するプロキシです。オフライン対応・キャッシュ・プッシュ通知などPWAの中核技術です。
このブラウザの Service Worker 状態
確認中...
Service Worker のライフサイクル
register()→installing→installed/waiting→activating→activated
コード例:Service Worker の登録
js
// メインスクリプト(main.js)
// Service Worker の登録
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
try {
const reg = await navigator.serviceWorker.register('/sw.js', {
scope: '/', // 管理するパスの範囲
});
console.log('登録成功:', reg.scope);
// アップデート確認
reg.update();
// 新しいSWが待機中のとき
reg.addEventListener('updatefound', () => {
const newWorker = reg.installing;
newWorker.addEventListener('statechange', () => {
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
// 新バージョンが利用可能
showUpdateBanner();
}
});
});
} catch (err) {
console.error('登録失敗:', err);
}
});
}
// 登録解除
const reg = await navigator.serviceWorker.getRegistration();
await reg.unregister();コード例:Service Worker 本体(sw.js)
js
// sw.js(Service Worker ファイル)
const CACHE_NAME = 'my-cache-v1';
const URLS_TO_CACHE = ['/', '/app.js', '/styles.css', '/offline.html'];
// インストール時:リソースをキャッシュ
self.addEventListener('install', (e) => {
e.waitUntil(
caches.open(CACHE_NAME).then(cache => cache.addAll(URLS_TO_CACHE))
);
self.skipWaiting(); // すぐにアクティブにする
});
// アクティベート時:古いキャッシュを削除
self.addEventListener('activate', (e) => {
e.waitUntil(
caches.keys().then(keys =>
Promise.all(keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k)))
)
);
self.clients.claim(); // 既存のページも管理下に
});
// フェッチ時:キャッシュ優先(Cache First)
self.addEventListener('fetch', (e) => {
e.respondWith(
caches.match(e.request).then(cached => {
if (cached) return cached; // キャッシュがあれば返す
return fetch(e.request) // なければネットワーク
.then(res => {
const clone = res.clone();
caches.open(CACHE_NAME).then(c => c.put(e.request, clone));
return res;
})
.catch(() => caches.match('/offline.html')); // オフライン時
})
);
});キャッシュ戦略の比較
| 戦略 | 動作 | 適した用途 |
|---|---|---|
| Cache First | キャッシュ→なければNetwork | 静的アセット(CSS/JS/画像) |
| Network First | Network→失敗したらCache | API・動的コンテンツ |
| Stale While Revalidate | Cacheを返しつつ、バックグラウンドで更新 | 頻繁に更新されるコンテンツ |
| Cache Only | Cacheのみ(Networkなし) | 完全オフラインアプリ |
NEWWorkbox(Google製 Service Worker ライブラリ)& Background Sync
Service Workerの実装を簡略化するGoogleのライブラリです。Next.js/Viteとの統合も容易です。
js
// Workbox(npm install workbox-window workbox-precaching)
import { Workbox } from 'workbox-window';
const wb = new Workbox('/sw.js');
wb.register();
// sw.js(Workbox製)
import { precacheAndRoute } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { CacheFirst, NetworkFirst } from 'workbox-strategies';
precacheAndRoute(self.__WB_MANIFEST); // ビルド時に自動生成
registerRoute(
({ request }) => request.destination === 'image',
new CacheFirst({ cacheName: 'images' })
);
// Background Sync(オフライン時の送信をキューイング)
// 接続が回復したら自動的に送信
import { BackgroundSyncPlugin } from 'workbox-background-sync';
registerRoute(
({ url }) => url.pathname.startsWith('/api/'),
new NetworkOnly({ plugins: [new BackgroundSyncPlugin('apiQueue')] }),
'POST'
);🤖 AIプロンプトテンプレート
以下のようなService Workerの登録・キャッシュ・オフライン対応のサンプルコードを生成してください: - navigator.serviceWorker.register()でSWを登録する基本実装 - installイベントでcaches.addAll()を使った事前キャッシュの実装 - fetchイベントでCache FirstとNetwork Firstのキャッシュ戦略を切り替える方法 - activateイベントで古いキャッシュバージョンを削除するパターン - updatefoundイベントで新バージョン検知時にユーザーに通知する実装
⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。