🚀

PWA を実装した

2023/04/28に公開約5,200字

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(),
])));

ナビゲーション先読みを有効にすることができます。

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 でアイコンの用途が指定できます。monochromemaskableany などです。

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

ログインするとコメントできます