PWAを実装した
Progressive web apps を実装しました。サイトをインストールしたり、オフラインで動かしたりできるようになりました。
<link rel="manifest" href="path/to/app.webmanifest">
<script>navigator.serviceWorker?.register("/service-worker.js").then(_onFulfilled).catch(_onRejected)</script>
Lighthouseで検証できます。
Service Worker
ネットワークリクエストやキャッシュの制御ができます。サイトのオフライン動作を助けてくれます。
// service-worker.js
self.addEventListener("install", _oninstall);
self.addEventListener("activate", _onactivate);
self.addEventListener("fetch", _onfetch);
Service Worker ファイルの更新はブラウザによって検出されるようです。
install
イベント
Service Worker がインストールされるときに発行されます。
self.addEventListener("install", event => event.waitUntil(Promise.all([_addResourcesToCache(), self.skipWaiting()])));
ServiceWorkerGlobalScope.skipWaiting
更新を即座に有効にすることができます。
activate
イベント
Service Worker が有効化されるときに発行されます。
self.addEventListener("activate", event => event.waitUntil(Promise.all([
!self.registration.navigationPreload ? Promise.resolve() : self.registration.navigationPreload.enable(),
_deleteOldCaches(),
self.clients.claim(),
])));
NavigationPreloadManager.enable
Clients.claim
登録された Service Worker を、再読み込みせずに使用できるようになります。
fetch
イベント
サイトのリソースが読み込まれるときに発行されます。
self.addEventListener("fetch", event => _cacheFirst());
キャッシュ
.htaccessファイルなどで制御しておくと、Service Worker がキャッシュを更新するときに、新しいリソースだけをサーバーから取得するようにできます。
<ifModule mod_headers.c>
Header set Cache-Control "max-age=0"
</ifModule>
max-age
キャッシュの寿命が指定です。
Web app manifests
サイトがインストールできるようになります。
.webmanifest拡張子のJSONファイルです。ブラウザは.json拡張子にも対応してくれるようです。
{
"short_name": "アプリの名前",
"name": "アプリの名前",
"icons": [{
"src": "path/to/icon.svg",
"type": "image/svg+xml",
"purpose": "monochrome",
"sizes": "any"
}],
"description": "説明"
}
必須
short_name
又はname
アプリの名前です。
icons
アイコンです。画像オブジェクトの配列で、各オブジェクトのpurpose
でアイコンの用途が指定できます。monochrome
、maskable
、any
などです。
192×192と512×512のアイコンを用意するとよいようです。一方でSVGに対応するブラウザもあります。
start_url
URLです。
"start_url": "/"
ここではトップページを指定しています。
background_color
スプラッシュ画面の背景色です。
"background_color": "black"
ページのbackground-color
と一致しているとよいようです。
display
ブラウザUIの表示です。
"display": "standalone"
ここでは単独アプリのように表示しようとしています。
対応していない場合は、ブラウザが特定の順番で代わりの方法を決定するようです。display_override
でその順番が変更できます。
scope
ナビゲーションスコープです。
"scope": "/"
ここではトップページを指定しています。
theme_color
テーマカラーです。
"theme_color": "yellow"
HTMLの<meta name="theme-color">
タグでも指定できます。media
属性と合わせてシステムのテーマに対応することもできます。
<meta name="theme-color" media="(prefers-color-scheme: light)" content="yellow">
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="lightyellow">
ここでは、いわゆるライトモードのときにyellow
、ダークモードのときにlightyellow
をテーマカラーとするよう指定しています。
lang
言語タグです。
"lang": "ja-JP"
ここでは日本の日本語を指定しています。
orientation
画面の向きです。
"orientation": "any"
ここでは任意の向きを指定しています。
Discussion