PWAの基礎知識(その3)「オンライン、オフライン判定」
PWA(Progressive Web App)という単語がトレンドになっています。PWAは特定の技術を指す言葉ではなく、様々な技術が組み合わさったスマートフォンにおけるWebアプリのベストプラクティスと言えます。
今回はそんなPWAの基礎になる、Service Workerについて紹介します。
利用できるWebブラウザについて
Can I useによると、モダンなブラウザの中でService Workerが使えないのはIEとOpera miniだけになっています。スマートフォンであれば安心して利用できるようになっています。
オンライン/オフラインは navigator.onLine で判定する
オンラインかオフラインの判定として使えるのが navigator.onLine です。trueの場合はオンライン、falseはオフラインです。
オフラインの時だけ表示を変える
ではオンラインの時だけユーザがそれと分かるように表示してあげましょう。ただしService WorkerはDOMが使えませんので、文字を出すことはできません。そこで、SVG(または画像)を使います。
二つのSVGをキャッシュする
まずオンライン、オフライン用のSVGを二つ読み込みます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
self.addEventListener('install', e => { | |
// インストール時に実行 | |
e.waitUntil( | |
caches.open('mismith').then(cache => { | |
return cache.addAll([ | |
'/', | |
'/client.js', | |
'/style.css', | |
'/ok.svg', // オンライン用 | |
'/fail.svg' // オフライン用 | |
]) | |
.then(() => self.skipWaiting()); | |
}) | |
); | |
}); |
HTMLの修正
HTML側はオンライン時の表示としておきます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<p> | |
Network status: <img src="ok.svg" width="20px" /> | |
</p> |
表示判定処理
そして、キャッシュを表示する fetch 処理にてオンライン、オフライン状態に応じてレスポンスを変えます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
self.addEventListener('fetch', e => { | |
// 外部リソース取得時 | |
const url = new URL(e.request.url); | |
// オフラインの時にはfail.svgを表示する | |
if (url.origin == location.origin && url.pathname == '/ok.svg' && !navigator.onLine) { | |
return e.respondWith(caches.match('/fail.svg')); | |
} | |
// それ以外の場合は同じ | |
e.respondWith( | |
caches.match(e.request, { | |
ignoreSearch: true | |
}) | |
.then(response => { | |
return response || fetch(e.request); | |
}) | |
); | |
}); |
こうするとオフライン時にはオフライン用のSVG画像を出せるようになります。
PWAではある程度のオフライン状態でも利用できますが、それでも最近のWebアプリとしてはネットワークがないと機能不足になってしまうでしょう。そうした時にJavaScript側でエラー処理を行うのはもちろんですが、ユーザの視覚にも反映してあげるとユーザビリティが高いと言えます。
コメントは受け付けていません。