Service Worker

ブラウザとネットワークの間でプロキシとして動作し、オフライン対応やキャッシュ制御を実現する Web API

APIフロントエンド

Service Worker とは

Service Worker は、ブラウザとネットワークの間でプロキシとして動作する JavaScript で、ネットワークリクエストのインターセプト、キャッシュ制御、オフライン対応、プッシュ通知を実現する。PWA (Progressive Web App) の基盤技術だ。

ライフサイクル

1. 登録 (Register)
   navigator.serviceWorker.register('/sw.js')

2. インストール (Install)
   → 静的アセットをキャッシュにプリキャッシュ

3. アクティベート (Activate)
   → 古いキャッシュを削除

4. フェッチ (Fetch)
   → ネットワークリクエストをインターセプト

登録

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js');
}

キャッシュ戦略

戦略 説明 用途
Cache First キャッシュを優先、なければネットワーク 静的アセット (CSS, JS, 画像)
Network First ネットワークを優先、失敗したらキャッシュ API レスポンス
Stale While Revalidate キャッシュを返しつつ、バックグラウンドで更新 頻繁に更新されるデータ

Cache First の実装

// sw.js
const CACHE_NAME = 'v1';
const PRECACHE_URLS = ['/index.html', '/styles.css', '/app.js'];

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then(cache => cache.addAll(PRECACHE_URLS))
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then(cached => cached || fetch(event.request))
  );
});

Workbox (Google のライブラリ)

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' })
);

registerRoute(
  ({ url }) => url.pathname.startsWith('/api/'),
  new NetworkFirst({ cacheName: 'api' })
);

オフライン対応

self.addEventListener('fetch', (event) => {
  event.respondWith(
    fetch(event.request).catch(() => caches.match('/offline.html'))
  );
});

注意点

  • HTTPS でのみ動作 (localhost は例外)
  • DOM にアクセスできない (Web Worker と同様)
  • 更新が即座に反映されない (次回アクセス時にアクティベート)

Service Worker の理解を深めるには関連書籍が参考になる。

関連用語