JavaScriptで動きをもたせたWebページは、 PWA(Progressive Web Apps)の形式を整えることで、 スマートフォン上でオフラインでも動作するアプリとして登録できる。
以下の手順で作成する。
アプリ起動時のためのアイコンを作成する。通常複数のサイズで作成するが、 最低限192x192の物を用意する。この例では ./img/appicon-192.png のファイル名で配置するものとする。
ブラウザのアドレスバー等に表示されるiconファイルも作成しておくとよい。
convert -resize 32x32 img/appicon-192.png img/favicon.ico
主要なHTMLファイルと、そこから呼び出しているCSSファイル、
JavaScriptソースファイル、画像ファイルをもれなく列挙し、
以下で作成する serviceworker.js
内の配列変数に代入する。
以下のようなほぼ決まった内容で serviceworker.js を作成する。 最初の2つの変数には
index.html
,
主体となるJavaScriptプログラムファイル、アプリのアイコンファイルは
必要で、その他CSSや利用しているデータファイル画像ファイルなどがあれ
ば記述する。var cacheName = 'AnyStringToIdentify-NandemoKandemo'; var filesToCache = [ './', './index.html', './main.js', './main.css', './img/appicon-192.png', './img/favicon.ico' ]; self.addEventListener('install', function(event) { console.log('ServiceWorker installing'); event.waitUntil( caches.open(cacheName).then(function(cache) { console.log('Service Worker caching app shell'); return cache.addAll(filesToCache); }) ); }); self.addEventListener('activate', function(event) { console.log('Service Worker activating'); event.waitUntil( caches.keys().then(function(keyList) { return Promise.all(keyList.map(function(key) { if (key !== cacheName) { console.log('Service Worker removing old cache', key); return caches.delete(key); } })); }) ); return self.clients.claim(); }); self.addEventListener('fetch', function(event) { console.log('Service Worker fetching', event.request.url); event.respondWith( caches.match(event.request).then(function(response) { return response || fetch(event.request); }) ); });
実行部はほぼ定形なので、先頭部分のキャッシュ識別名と、 キャシュすべきファイル一覧を間違わずに記述する。 作成ファイルを追加したときにこの部分の更新を忘れると悩むことになる。
上の例でメインとなるJavaScriptファイルが main.js
だとすると、そこから serviceworker.js
をロードする記述を埋め込む。仮に index.html
から main.js
を
<script type="text/javascript" src="main.js"></script>
と読み込んでいるのだとすると、main.js
には以下のような記載が必要になる。
document.addEventListener("DOMContentLoaded", ()=>{ // // main.js でやろうとしている処理がここに書いてあるものとする。 // if ('serviceWorker' in navigator) { navigator.serviceWorker.register('./serviceworker.js') .then(()=> { console.log('service worker registered'); //なくてもよい }); } }, false);
アプリケーション登録に必要な情報をJSON形式でファイルに書き込み、 それを主要HTMLファイルのlink要素から取り込む。
ファイル名は何でもよいが、一般的には manifest.json として アプリ登録に必要な項目を埋めて作成する。
{ "name": "PWA Sample", "short_name": "PWAs", "icons": [{ "src": "./img/appicon-192.png", "sizes": "192x192", "type": "image/png" }], "theme_color": "#c0c0c0", "background_color": "#ddf", "display": "standalone", "start_url": "./index.html" }
上で作成したJSONファイルを呼び出し側のHTML からリンクする。以下のものをhead要素内に追加する。
<link rel="manifest" href="manifest.json">
これまでの手順をまとめ、以下のファイル群をPWA化した例を示す。
ファイル名 | 役割 |
---|---|
pwa-sample.html
| 開始ページ(start_url) |
pwa-sample.js
| 本体jsファイル |
pwa-sample.css
| CSS定義ファイル |
pwa-svw.js
| ServiceWorker定義jsファイル |
pwa-manifest.json
| manifestファイル |
img/pwa-sample-192.png
| アイコンファイル |
img/pwa-sample.ico
| icoファイル |
img/A.png
| データファイルその1 |
img/B.png
| データファイルその2 |
PWAに限らず、スマートフォンのブラウザで見るときには CSSやjsファイルを更新後に単にリロードしても更新前のものが本体に キャッシュされて修正を確認できない。PC用ブラウザの場合はSHIFTを 押しながらリロード(スーパーリロード)することで解決できることがあるが、 それでも効かないときは、ブラウザの履歴消去機能でキャッシュを消さねばならない。
PC用ブラウザやAndroidのChromeでは、ブラウザメニューの履歴から 進むと一定時間のキャッシュをサイトごとに消去できるのでこれを利用する。 iPhoneのSafariではかなり複雑なので 「ios safari キャッシュ 消えない js」 などのキーワードで検索して調べる。
本来アイコンは複数のサイズで使うが、別デザインで作るのが大変なときは、
大きめのサイズ(例えば512x512)で作って、小さい方にリサイズする。
たとえば myicon512x512.png
だけ作ったのなら、
convert -reisze 192x192 myicon192x192.png myicon512x512.png convert -reisze 180x180 myicon180x180.png myicon512x512.png
などのようにconvertでリサイズ変換する。
また、icoファイルはGIMPでエクスポートするときに拡張子を .ico で書き出すと作成できる。