4月8日開催のアシアル技術セミナー Vo.2 Webフロントエンド開発最前線 ~SPAおよびPWA開発プロジェクトの現場から~ 「はじめてのPWA開発」
初めてのあなたのWebサイトがPWAになるまで小椋 陽太 アシアル株式会社開発1Youta OGURA
View Slide
PWAの基礎知識を知るService Workerを知るPWAを実装する参考2
PWAの基礎知識を知るService Workerを知るPWAを実装する参考PWAとはPWAが実現すること3
PWAの基礎知識を知る > PWAとは● Reliable● Fast● Engaging低速なネットワークや無線状態でも利用できるコンテンツやアニメーションを高速で描画できるネイティブアプリのように直感的に操作ができる=4Googleが推進する先進的なモバイルウェブのユーザー体験の指針
段階的 レスポンシブネットワーク接続に依存しないアプリ感覚常に最新安全 再エンゲージメント可能リンク可能PWAの基礎知識を知る > PWAが実現することインストール可能発見しやすい5
段階的 レスポンシブネットワーク接続に依存しないアプリ感覚常に最新安全 再エンゲージメント可能リンク可能PWAの基礎知識を知る > PWAが実現することインストール可能発見しやすい6
オフラインでも、遅いネットワーク環境でも 高速で動作面倒な再インストールなしで 自動アップデートネイティブアプリのように端末に インストール常に最新PWAの基礎知識を知る > PWAが実現すること7ネットワーク接続に依存しないインストール可能
そこで重要なのが Service Worker8
PWAの基礎知識を知るService Workerを知るPWAを実装する参考Service WorkerとはService Workerを利用したPWAの基本構造Service Workerのライフサイクル9
● アプリとサーバとの間でネットワークリクエストを監視● アプリに必要なリソースをキャッシュストレージから提供● キャッシュストレージを最新に維持ServiceWorker=Service Workerを知る > Service Workerとは10アプリごとにブラウザに登録され、バックグラウンドで動くスクリプト
Service Worker のイベント11Service Workerを知る > Service Workerを利用したPWAの基本構造UninstallActivateInstallWaitブラウザへ登録される更新の登録待ちをする ブラウザへの登録を解除されるアプリを制御できる状態になる
ServerClientApplicationService Worker & Cache Storage12ActivateService Workerを利用したPWAの基本構造 - アクティベートされている場合
ServerClientApplicationService Worker & Cache Storage13InstallService Workerを利用したPWAの基本構造 - 初めて登録される場合
ClientApplicationService Worker & Cache Storage14ServerUninstallWaitService Workerを利用したPWAの基本構造 - 更新された場合
wait初回2回目以降更新ありuninstall起動 状態遷移install activateactivateinstall ・アセットをキャッシュ・リクエストを監視・データをキャッシュ・アセットを再キャッシュ・リクエストを監視・データをキャッシュ15処理内容Service Workerを知る > Service WorkerのライフサイクルOLDNEW
PWAの基礎知識を知るService Workerを知るPWAを実装する参考PWA化の必要要件Service Worker を作成するウェブアプリマニフェストを作成する16
ネットワーク接続に依存しない常に最新 インストール可能17PWAを実装する > PWAの必要要件の必要要件
ネットワーク接続に依存しない常に最新 インストール可能18の必要要件PWAを実装する > Service Workerを作成する
インストール時にアセットをキャッシュするアセットのリクエストを検知するデータのリクエストを検知するアセットの更新時に古いキャッシュを削除するSTEP1STEP2STEP3STEP4Service Worker を作成する19PWAを実装する > Service Workerを作成する
<br/>if ('serviceWorker' in navigator) {<br/>// 対応しているブラウザでService Worker登録<br/>navigator.serviceWorker<br/>.register('/service-worker.js')<br/>}<br/>20index.htmlPWAを実装する > Service Workerを作成するservice-worker.js を新規作成STEP0HTMLに登録処理を実装Service Worker 登録処理
var filesToCache = ['/', // index.html'/app.js','/manifest.json','/style.css','/jquery-3.3.1.min.js',]self.addEventListener('install', function(e) {e.waitUntil(// cacheNameをキーにキャッシュ保存caches.open(cacheName).then(function(cache) {return cache.addAll(filesToCache); // or cache.add}))})STEP121PWAを実装する > Service Workerを作成するservice-worker.jsインストール時にアセットをキャッシュするインストールを検知アセットをキャッシュ
STEP2 self.addEventListener('fetch', function(e) {// 一致するものがあればキャッシュを返し// なければサーバーにリクエストするe.respondWith(caches.match(e.request).then(function(response) {return response || fetch(e.request)}))})22PWAを実装する > Service Workerを作成するアセットのリクエストを検知するservice-worker.jsアセットのリクエスト検知キャッシュからレスポンス返却
STEP3-1 self.addEventListener('fetch', function(e) {var dataUrl = 'https://api...get.php'if (!e.request.url.indexOf(dataUrl)) {// データ取得URLの場合常にキャッシュを最新化e.respondWith(fetch(e.request).then(function(response) {return caches.open(dataCacheName).then(function(cache) {cache.put(e.request.url, response.clone())return response})})) // 以下省略 23PWAを実装する > Service Workerを作成するデータのリクエストを検知するservice-worker.jsデータのリクエスト検知Service Workerの処理
STEP3-2const dataUrl = 'https://api.../get.php'let dataset = []if ('caches' in window) {// まずキャッシュからデータを取得caches.match(dataUrl).then(function (res) {dataset = res || []})}$.get(dataUrl, {fmt: 'json'}, function (res) {// 後からサーバーからデータを取得dataset = res || []}) 24app.jsPWAを実装する > Service Workerを作成するデータのリクエストを検知するキャッシュからデータを取得サーバーからデータを取得
self.addEventListener('activate', function(e) {e.waitUntil(caches.keys().then(function(keys) {return Promise.all(keys.map(function(key) {if (key !== cacheName) {// キーが違う場合古いものを削除return caches.delete(key)}}))}))})25STEP4PWAを実装する > Service Workerを作成するアセットの更新時に古いキャッシュを削除するservice-worker.jsService Workerの差分を確認キャッシュのキーが違う場合古いキャッシュを削除
ネットワーク接続に依存しない常に最新 インストール可能26の必要要件PWAを実装する > ウェブアプリマニフェストを作成する
ウェブアプリマニフェストを作成する27マニフェストファイルを定義するHTMLから参照するSTEP1STEP2PWAを実装する > ウェブアプリマニフェストを作成する
28ウェブアプリマニフェスト=● アイコン● テーマカラー● アプリ名 ・・・etcPWAを実装する > ウェブアプリマニフェストを作成するアプリをインストールするためのメタデータを定義するjsonファイル
29{"icons": [{"src": "/icon_512x512.png","sizes": "512x512","type": "image/png"}],"name": "My Progressive Web App","short_name": "MyPWA","display": "standalone","start_url": ".","description": "My awesome Progressive Web App!","background_color": "#ffffff"}manifest.jsonSTEP1マニフェストファイルを定義するPWAを実装する > ウェブアプリマニフェストを作成するmanifest.json を新規作成JSON形式でメタデータを定義
30index.htmlSTEP2 タグを設定するHTMLから参照するPWAを実装する > ウェブアプリマニフェストを作成する
ネットワーク接続に依存しない常に最新 インストール可能31PWAを実装するの必要要件
PWAの基礎知識を知るService Workerを知るPWAを実装する参考32さらにProgressiveに参考サイト
33UI/UXさらにProgressiveにレスポンシブデザインクロスブラウザ対応アニメーションSNSシェア対応Performance初回ロードの高速化キャッシュ戦略の最適化アップデートの効率化OthersSEO対策PUSH通知オフライン状態通知
34参考サイト● はじめてのプログレッシブ ウェブアプリ - Google Developers○ https://developers.google.com/web/fundamentals/codelabs/your-first-pwapp/?hl=ja● Service Worker の紹介 - Google Developers○ https://developers.google.com/web/fundamentals/primers/service-workers/?hl=ja● Progressive Web App Checklist - Google Developers○ https://developers.google.com/web/progressive-web-apps/checklist● PRPLパターン - Google Developers○ https://developers.google.com/web/fundamentals/performance/prpl-pattern/● Caching best practices & max-age gotchas - Jake Archibald○ https://jakearchibald.com/2016/caching-best-practices/● What, Exactly, Makes Something A Progressive Web App? - Infrequently○ https://infrequently.org/2016/09/what-exactly-makes-something-a-progressive-web-app/● ウェブアプリマニフェスト - MDN web docs○ https://developer.mozilla.org/ja/docs/Web/Manifest
35