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