Flask+Service Worker on Heroku で PWA チュートリアル
概要
自分にとっては dev.to でバズった Service Worker。
その概要と機能性をなぞってみようとチュートリアル的に学んだ内容をまとめました。
掲題の通り、Flask + Service Worker を Heroku で動作させ、PWA(Progressive Web Apps) してみました。
さらなる sleep 対策として
Service Worker があればオフラインでもサービス動作させられるし、sleep し続けてもいいのでは?と思い、導入してみました。
Flask に Service Worker 導入
ソースは git にあります。
簡単に導入時のポイント
- app.py というメインスクリプトに
/sw.js
へのアクセスできるようにします。
1 | @app.route('/sw.js', methods=['GET']) |
- static ディレクトリ内に空の sw.js を配置
基本、上記 2 step をしてから Service Worker の各処理を実装していきます。
Install
以下の install イベントでは、指定したキャッシュさせたいファイルパスを全てキャッシュさせています。
挙動のイメージとしては、トップページにアクセスした際に Service Worker がブラウザに導入(install)されるイベントの発生時にキャッシュを生成しています。
1 | var urlsToCache = [ |
Chrome > Developer Tool > Application > Cache Storage を見るとキャッシュされているのがわかります。
fetch
以下処理は、fetch イベントでブラウザでキャッシュしたファイルを呼び出しています。
1 | self.addEventListener('fetch', function (event) { |
activate
Service Worker は active 状態になってもすぐにブラウザ上のリソースを操作できず、
もう一度ページにアクセスした際にできるようになっています。
その為、一度しかアクセスしないユーザにとっては Service Worker によるパフォーマンスの向上を体験できないことになります。
その為、 以下 activate イベントによって直ちに操作できるようにします。
1 | self.addEventListener('activate', (event) => { |
基本、以上の設定で Service Worker 導入完了でした。
前後を比較すると Waterfall で見る、リソースのロードタイムがキュッと縮んでいるのがわかります。
Before
After
まとめ
Service Worker で一度キャッシュさせた後はオフラインでも動作するような仕組みが作れました。
オフラインでも動作する、というのは魅力的 ♪
ただし、クエリパラメータのパターンの多い URL がある場合などは
キャッシュされにくく、この場合のキャッシュ戦略としては、ひとまず静的ファイルのみキャッシュするなどで対応するのが良いのか、
等考えさせられるところがありました。
例)
1 | /ts?circuit_id=1&station_id=1 はアクセスしたけど |
また、POST method は Service Worker は未対応で issue が上がっているようです。
Workaround として以下提案がされているブログがありましたが、実装が複雑で、まだこの辺りは開発の余地がある印象です。
以下 Service Worker 導入時の苦労した点があり、涙無くして見られない内容でした。
日経電子版 サイト高速化と PWA 対応
他趣味アプリで Workbox を利用していますが、
こちらも書いていきたいと思います。
参考
Flask+Service Worker on Heroku で PWA チュートリアル
https://kenzo0107.github.io/2018/08/13/2018-08-14-flask-service-worker-on-heroku-pwa/