PWAでWeb APIを使う際の注意点
Webアプリにおいて、Web APIを使わないことはほぼ皆無でしょう。PWAにおいてももちろん同じようにWeb APIを使って実装されるでしょう。しかし、幾つかのハマりどころがあるので注意が必要です。
キャッシュ時にはヘッダー情報などが使われない
キャッシュは以下のようなフォーマットで実装されます。
cache.put(url, response); |
単純にURLをキーとして、そのレスポンスを登録するだけなので、Web APIアクセスする際にヘッダー情報を追加したり、細かなカスタマイズができません。そこで、ネットワークが使える際にコンテンツをWebブラウザ側で取得し、その結果をService Workerで登録します。
例えばレスポンスが req 、結果が body という変数であったならば、以下のように Service Workerを呼び出します。
const channel = new MessageChannel(); | |
navigator.serviceWorker.controller | |
.postMessage({ | |
action: 'cache', | |
url: res.req.url, | |
response: body | |
}, [channel.port2]); |
そしてService Worker側でコンテンツを保存します。Responseオブジェクトを使ってレスポンスを動的に作るのがコツです。Webブラウザ側のResponseオブジェクトをそのまま渡せないので注意してください。
self.addEventListener('message', e => { | |
if (e.data.action == 'cache') { | |
caches.open(CACHE_NAME) | |
.then((cache) => { | |
const res = new Response(e.data.response); | |
cache.put(e.data.url, res); | |
}) | |
} | |
}); |
こうすると、該当URLへのアクセスすると、ヘッダー情報を無視して結果が取得できます。HTTPメソッドも無視されるので注意してください。
ただし、この方法だとオンライン時のキャッシュの更新が必要で複雑になりすぎる可能性があったり、検索のようにクエリーが動的に変わる場合に対応できないでしょう。
navigator.onLineを使う
もう一つはnavigator.onLineを使って、オンラインの場合はWeb APIを呼び出して、オフラインの場合は自作のキャッシュを使う方法があります。キャッシュはネットワークアクセスの結果をlocalStorageやIndexedDBに保存すれば良いでしょう。
この方法の場合はオンライン、オフライン時の条件分岐が増えてしまう問題があります。できればクラスでラッピングし、アプリケーションからはネットワークの状態を気にせずに利用できるようにするのが良いでしょう。
この方法の利点はHTTPメソッドごとの処理を細かく制御できることで、同じURLになりがちな一覧の取得とデータ作成(GET / と POST /)を分けられることです。
PWAにおいてはネットワークの状態をきちんと制御するのが肝になるでしょう。それによってユーザ体験が大きく変わってきます。ユーザが不自然に感じたり、使いづらいと感じないシステムを作るためにも、キャッシュを上手に活用しましょう。
コメントは受け付けていません。