自分用のメモですが何かの参考になれば幸いです。
参考動画を引用しているのが多々あります。
サービスワーカーの概要は過去記事を参考にしてください
サンプルソースをもとにライブラリーなしで導入する記事です。
環境構築
サンプルがあったのそちらをもとにサービスワーカーを実際にいれてみます
git clone https://github.com/webopt/ch9-service-workers.git cd ch9-service-workers npm install node http.js
起動した画面はこちらになる
http://localhost:8080/
この時点では何もサービスワーカーが動いていない
ソースの構成は以下のとおりで こちらのsw-install.jsとsw.jsを触っていく
htmlの最後にsw-install.jsが読み込まれるようになっている
serviceWorker対応チェック
まずはserviceWorkerが対応しているのか確認する
実行結果
コンソールログに成功したログが表示されている。
インストール
実際にサポートされているのがわかったので次はインストールする。
window.addEventListenerのloadイベントをとって関数にわたす(アロー関数)
navigator.serviceWorkerのオブジェクトを利用してインストールする
成功した場合はregにわたされる。失敗した場合はcatchする
アプリケーションのタブを確認するとインストールされている事が確認できる
インストールされたservice worker側が動いているのか確認する
ちなみにリロードするとservice worker側のログは表示されない
activeのイベントを追加する
もしログが表示されない場合はapplicationのタブでService WorkerをUnregistedを実行するとでてくる
この段階ではService Workerにキャッシュされていないのでオフラインにした場合はもちろん動かない
キャッシュファイルの追加
キャッシュさせる名前のファイル名をつける
const cacheName = 'v1'; const cacheAssets = [ 'index.html' ,'about-me.html' ,'/css/global.css' ,'/js/attach-nav.js' ,'/js/debounce.js' ,'/js/nav.js' ];
1つでもファイル名を間違えるとキャッシュされないみたい・・・
installイベントにHTMLなどをキャッシュさせる行為を追加する
e.waitUntil( caches .open(cacheName) .then(cache => { console.log('Service Worker: Caching Files'); cache.addAll(cacheAssets); }) .then( () => self.skipWaiting()) )
全体は以下のとおり キャッシュさせるとapplicationの所にcacheが追加される。
キャッシュはさせたがこの段階では通信を横取りする機能がないのでオフライン時はエラーになる。
キャッシュファイルの削除
cacheNameで設定した名前でキャッシュされる名前をかえると別名でキャッシュされる
const cacheName = 'v2'; //v1 -> v2
だた前の部分が消えるわけではない。前のキャッシュをクリアする処理をアクティブイベントに追加する
e.waitUntil( caches.keys().then(cacheNames => { return Promise.all( cacheNames.map(cache => { if(cache !== cacheName){ console.log('Service Worker: Clearing Old Cache'); return caches.delete(cache); } }) ) }) );
fetchイベントを追加する(横取り機能)
// Fetchイベント(横取り) self.addEventListener('fetch',e => { console.log('Service Worker: sw.js Fetching '); e.respondWith(fetch(e.request).catch(() => caches.match(e.request))); });
これでオフラインでも表示できるようになる
ちなみに上記の画像のofflineとupdate onloadをクリックしてオフラインにします
全体は以下のとおり
横取り機能をアクセスごとに変更する
すべてのファイルをcacheAssetsに書くのは現実的ではないので fetchイベントに追加して、キャッシュさせる
// Fetchイベント(横取り) self.addEventListener('fetch',e => { console.log('Service Worker: sw.js Fetching '); e.respondWith( fetch(e.request) .then(res => { //リクエストのコピーをする const resClone = res.clone(); //キャッシュを開く caches .open(cacheName) .then(cache => { cache.put(e.request, resClone); }); return res; }).catch(err => caches.match(e.requset).then(res => res) ) ); });
インストール時のイベントやcacheAssetsも削除する 全体は以下のとおり
キャッシュされるのが確認できる(オフラインでも使えた)
感想
導入の1からソースを書いたので理解がふかまった。でもソースが長くなりそうなので次回はgoogle先生のライブラリーのWorkboxを使って導入したい。