PWAにおけるキャッシュの更新方法
PWAで一番厄介な問題と言えばキャッシュではないでしょうか。開発中などで、キャッシュを更新したい時にできなかったり、キャッシュを読み込んでしまって修正が反映されずにバグ解決に時間を取られるかも知れません。
そこでちょっとしたTipsを紹介します。
Service Worker登録時の工夫
それは registration.onupdatefound
を仕込んでおくということです。このメソッドはService Workerが更新されているかどうかを検知してくれます。もし更新されている場合は、updateメソッドを使って更新できます。
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
if ('serviceWorker' in navigator) { | |
navigator.serviceWorker | |
.register('/serviceworker.js') | |
.then(registration => { | |
// 登録成功 | |
registration.onupdatefound = function() { | |
console.log('アップデートがあります!'); | |
registration.update(); | |
} | |
}) | |
.catch(err => { | |
// 登録失敗 | |
}); | |
} |
ボタンで更新する
キャッシュをクリアしたい時のためにボタンを用意しておきましょう。unregisterメソッドを使えば一旦Service Workerを解除してくれるので、再読み込みすれば改めて登録し直してくれます。
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
navigator.serviceWorker.getRegistration() | |
.then(registration => { | |
registration.unregister(); | |
}) |
キャッシュされているスクリプトなどを更新する
Service Workerを使っている場合、JavaScriptやスタイルシートの変化を検知してアップデートする方法は恐らくなさそうです。何らかのアクションが必要になります。
例えばボタンを使う場合には以下のように、Service Worker側にメッセージを送ります。
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
const channel = new MessageChannel(); | |
navigator.serviceWorker.controller | |
.postMessage('update', [channel.port2]); |
そしてService Worker側でキャッシュを取得し直します。やっていることはインストール時と同じです。
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
var urlsToCache = [ | |
'/', | |
'/bower_components/jquery/dist/jquery.min.js', | |
'/bower_components/hifive/h5.js', | |
'/bower_components/hifive/h5.css', | |
'/bower_components/hifive/ejs-h5mod.js', | |
'/ncmb.min.js', | |
'/app.js' | |
]; | |
self.addEventListener('install', function(event) { | |
return install(event); | |
}); | |
self.addEventListener('message', function(event) { | |
return install(event); | |
}); | |
const install = (event) => { | |
return event.waitUntil( | |
caches.open(CACHE_NAME) | |
.then(function(cache) { | |
urlsToCache.map(url => { | |
return fetch(new Request(url)).then(response => { | |
return cache.put(url, response); | |
}); | |
}) | |
}) | |
.catch(function(err) { | |
console.log(err); | |
}) | |
); | |
} |
これでキャッシュの読み込み直しが完了します。ボタンを押さなくとも強制的に取得し直すといった仕組みでも良いかと思いますが、特定のURL(コンテンツなど)に限ったり、Service Workerが更新された時に限ると言った工夫は必要でしょう。
キャッシュによって表示を高速化するService Workerですが、使い方を間違えるとユーザビリティが大きく損なわれる可能性があります。キャッシュすべきコンテンツとしない方が良いコンテンツを見極めて、上手に運用しましょう。
コメントは受け付けていません。