プログレッシブウェブAMP
この記事はGoogle DevelopersのProgressive Web AMPsの日本語訳です。Progressive Web AMPsの多分一番いいチュートリアルです。
しかし、Service Worker, Promise, AMPに関して基礎的な知識がないと途中で挫折することになると思います。
そのような場合はこの記事をストック(←重要)した後、以下の参考記事を読むことをおすすめします。
-
そもそもプログレッシブウェブAMPって何?って方へ: https://www.suzukikenichi.com/blog/pwamp-is-combination-of-pwa-and-amp/
-
Service Workerって何?って方へ: https://developers.google.com/web/fundamentals/getting-started/primers/service-workers?hl=ja
-
Promiseって何?って方へ: http://azu.github.io/promises-book/
-
AMPって何?って方へ: https://www.ampproject.org/ja/learn/about-amp/
記事内の「※」付きのコメントは私が加えた補足です。
Google, Web関連を中心にソフトウェアの情報をキャッチアップしがちです。
Twitter: https://twitter.com/awjecc

1. 導入
AMPは、高速にレンダリングされる静的コンテンツ用のページを作成する方法です。プログレッシブWebアプリケーションは、Web上で信頼性が高く、迅速で魅力的な経験を提供します。開発者がAMPを使用してWebサイトでPWAを構築するには、いくつかの方法があります。
この記事で実装するもの
このCodelabでは標準AMPサイトをプログレッシブWebアプリケーションに変換して、さらにAppShellを使用して強化することによって、2つの異なるAMP + PWAパターンを実装する方法を説明します。
この記事で学ぶもの
AMPサイトをプログレッシブWebアプリケーションに変換する方法
App Shellを使用して経験を向上させる方法
必要なもの
- 最新のバージョンのChrome
- Node.js
- シンプルなコード
- テキストエディタ
- HTML, CSS, JavaScript, そしてChromeの開発ツールに関する基本的な知識
このcodelabは、AMPとプログレッシブWebアプリケーションに焦点を当てています。それと関連性の低いコードは、簡単にコピー&ペーストできるように表示されます。
2. セットアップ
コードをダウンロードする
ダウンロードをクリックするか、以下のGithubからプロジェクトをクローンしてください。
git clone https://github.com/googlecodelabs/amp-pwa.git
Node.jsをインストールする
このcodelab全体で、Service Woker の生成を支援するツールを使用します。
このツールはsw-precacheと呼ばれ、これを動かすにはNode.jsをインストールする必要があります。
OSにNode.jsをインストールする方法については、Node.jsのWebサイトを参照してください。
localhostで稼働する
このcodelabでは、ローカルファイルシステムのコンテンツを提供できる必要があります。
そのためにserveというNode.jsベースの静的コンテンツ・サーバーを使用します。
インストールするには、次のコマンドを実行します。
npm install -g serve
初期のコードを実行する
すべての部分が適切に配置されていることを確認します。
コンソールで、codelabソースコードがインストールされているディレクトリに移動し、その中の/workフォルダに移動します。
これは、このcodelab全体で使用するフォルダになります。workフォルダでserve
コマンドを実行するだけでサーバーを起動できます。
※ コマンドが見つからない場合はShell を再起動してみてください
Chromeでhttp://localhost:3000を開き、AMPインデックスページが表示されているかどうかを確認します。
※ 私の環境ではデフォルトでhttp://localhost:5000 でした
3. PWAの構成要素
※ PWAはProgressive Web Appsの略
- プログレッシブ - ブラウザにかかわらず、すべてのユーザーのために機能する。
- 応答性 - デスクトップ、モバイル、タブレットなどあらゆる要因に適合します。
- 接続に依存しない - オフラインまたは低品質のネットワークで作業するようにService Woker で強化する。
- App-like - App shellで構築されているため、アプリのようなの操作感やナビゲーションでユーザーにアプリみたいだと感じさせます。
- フレッシュ - Service Woker のアップデートプロセスのおかげで、常に最新の状態を保ちます。
- 安全 - スヌーピングを防止し、コンテンツが改ざんされていないことを保証するために、HTTPS経由で提供します。
- 発見しやすさ - W3CのマニフェストとService Woker の登録範囲のおかげで、検索エンジンがそれを「アプリケーション」として識別できます。
- 再訪問のしやすさ - プッシュ通知などの機能を使用して再訪問を容易にします。
- インストール可能 - ユーザーがアプリストアからインストールする手間をかけずにアプリをホーム画面に「置ける」ようにします。
- リンク可能 - URL経由で簡単に共有でき、複雑なインストールを必要としません。
4. Service Woker の追加
まず、アプリケーションのロゴイメージやフォントなどの静的コンテンツをキャッシュするService Woker を追加します。
service woker の作成を大幅に簡素化するJeffrey Posnickによって作成されたツールであるsw-precach
をインストールする
npm install -g sw-precache
work
フォルダの直下にsw-precache-config.js
というファイルを作り、以下のコードを追記します。
module.exports = {
staticFileGlobs: [
'img/**.*'
]
};
これによりsw-precache
が設定され、imagesディレクトリ以下のすべてのファイルとfontsディレクトリのすべてのファイルをキャッシュするService Wokerを作成します。
`sw-precacheを実行します。
sw-precache --config=sw-precache-config.js
※ コマンドが見つからない場合はShell を再起動してみてください
イメージとフォントをキャッシュするように設定されたservice-worker.js
ファイルが生成されます。
これらのフォルダで何かが追加または変更されるたびに、前のsw-precacheコマンドでService Woker を再生成する必要があります。
service woker の生成は、タスクの半分に過ぎません。
次のステップは、AMPページからService Woker をインストールすることです。
このためにamp-install-serviceworkerというものが提供されています。
各AMPページの</head>
タグの直前にService Woker Javascriptを追加して読み込みます。
※ work/index.htmlに追加すれば良いです。
<script async custom-element="amp-install-serviceworker"
src="https://cdn.ampproject.org/v0/amp-install-serviceworker-0.1.js">
</script>
各AMPページの</body>
タグの直前に以下の設定を追加する必要もあります。
※ work/index.htmlに追加すれば良いです。
<amp-install-serviceworker
src="/service-worker.js"
layout="nodisplay">
</amp-install-serviceworker>
AMPキャッシュからservice woker をインストールする
AMPキャッシュからjavascriptファイルを使用してservice woker をインストールすることはできません。
その代わり、amp-install-serviceworkerb
には、そのURLをiframeとしてロードし、AMPキャッシュからのService Woker のインストールを可能にするdata-iframe-src
という追加の属性があります。
workフォルダの直下にinstall-service-worker.html
ファイルを作成し次の内容を追加します。
<!doctype html>
<html>
<head>
<title>installing Service Woker</title>
<script type="text/javascript">
var swsource = "/service-worker.js";
if("serviceWorker" in navigator) {
navigator.serviceWorker.register(swsource)
.then(function(reg){
console.log('SW scope: ', reg.scope);
})
.catch(function(err) {
console.log('SW registration failed: ', err);
});
};
</script>
</head>
<body>
</body>
</html>
このページがiframeの内側から読み込まれると、このコードはService Woker の登録をします。
AMPファイルのamp-install-serviceworker
に戻り、このページへの参照を追加します。
amp-install-serviceworker
の設定は、次のようになります。
※ work/index.htmlの</body>
の直前記述を書き変えます。
<amp-install-serviceworker
src="/service-worker.js"
layout="nodisplay"
data-iframe-src="/install-service-worker.html">
</amp-install-serviceworker>
動作確認
Chromeでhttp://localhost:3000を開きます。
Chromeのメニュー > その他のツール > デベロッパーツールでツールを開きます。
Chromeデベロッパーツール内で、[アプリケーション]タブに移動し、[Service Woker]項目をクリックします。
上記のように、Service Woker がインストールされていることを確認できればオッケーです。
おめでとうございます!
静的コンテンツ(imagesフォルダ以下のすべてのファイルとフォントファイル)をキャッシュするService Woker を作成してインストールすることで、
AMPサイトをプログレッシブWebアプリケーションに変換するための第一歩を踏み出しました。
5. コネクティビティから独立させる
訪問したページをキャッシュする
ユーザーが訪問したページをキャッシュするには、sw-precache-config.js
にsw-precache
の別の設定を追加する必要があります。
以下のコードをstaticFileGlobs
属性の直後に追加します。
runtimeCaching: [{
urlPattern: '',
handler: (request, values, options) => {
// If this is NOT a navigate request, such as a request for
// an image, use the cacheFirst strategy.
if (request.mode !== 'navigate') {
return toolbox.cacheFirst(request, values, options);
}
// If it's a navigation request, use the networkFirst strategy.
return toolbox.networkFirst(request, values, options);
}
}]
※ 直前の行の]
を],
に書き換えないとエラーが出ます。
※ sw-precache --config=sw-precache-config.js
を実行するとservice-worker.js
が更新されます。
※ キャッシュを扱っているのでシークレットブラウザで開くことをおすすめします。
runtimeCaching
属性は、ハンドラ構成の配列を受け取ります。
このリクエストは(※ ページもしくは画像などのリソース構わず)すべてのリクエストを受け取るので、
request.mode
属性を使用して、ページまたはリソースのリクエストかどうかを確認し、
それぞれに異なるキャッシュ戦略を使用しています。
オフラインページを追加する
今、オフラインで以前に訪問したページにアクセスすると、そのページのキャッシュを見ることができます。
しかし、以前訪問していなかったリンクをユーザーがクリックすると、オフラインページが表示されます。
service woker を使用すると、オフラインページをカスタマイズできます。
workフォルダ内にoffline.html
ファイルを作成します。シンプルなオフラインページ
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>The Photo Blog - Offline</title>
<meta name="viewport"
content="width=device-width,minimum-scale=1,initial-scale=1">
</head>
<body>
<h1>You are Offline</h1>
</body>
</html>
sw-precache-config.js
を編集して、sw-precache
設定を更新します。
オフラインページをキャッシュするためにstaticFileGlobsのリストにオフラインページを追加します。
module.exports = {
staticFileGlobs: [
'img/**.*',
'offline.html'
],
...
すでに、toolbox.networkFirst
を使って、Promiseを返すコードを書きました。
しかし、ネットワークが使用できず、ファイルがキャッシュに見つからない場合、このPromiseは拒否されてしまいます。
リクエストが失敗したときにオフラインページを返すためにsw-precache-config.js
のtoolbox.networkFirst
メソッドコールの後にcatchセクションを追加します:
...
if (request.mode !== 'navigate') {
return toolbox.cacheFirst(request, values, options);
}
// If it's a request for content, use the networkFirst
// strategy, and send an offline page if both network and
// cache fail.
return toolbox.networkFirst(request, values, options)
.catch(() => {
return caches.match('/offline.html', {ignoreSearch: true});
});
...
AMPランタイムのキャッシュ
この時点で、キャッシュ・ページの1つをオフラインで開こうとすると、コンソール上に一連のエラーが発生したページが表示されます。
ページおよびサポートするコンテンツはキャッシュされていましたが、AMPランタイムはキャッシュされていなかったためです。
私たちのsw-precache
の設定をアップデートして、AMPランタイムも処理してみましょう。次のコードをruntimeCaching
の配列に追加します。
...
{
urlPattern: /cdn\.ampproject\.org/,
handler: 'fastest'
}
...
これは、AMPランタイムをfastest
戦略でキャッシュします。この戦略は、キャッシュとネットワークの両方からリソースを並行してリクエストします。
キャッシュされたバージョンが、通常使用可能な場合は返されます。
しかし、並列ネットワークリクエストは、キャッシュをAMPランタイムの最新バージョンに更新します。それは次回のリクエスト時に返されます。
この時点での、完全なsw-precache-config.js
は次のようになります。
module.exports = {
staticFileGlobs: [
'img/**.*',
'offline.html'
],
runtimeCaching: [{
urlPattern: '*',
handler: (request, values, options) => {
// If this is NOT a navigate request, such as a request for
// an image, use the cacheFirst strategy.
if (request.mode !== 'navigate') {
return toolbox.cacheFirst(request, values, options);
}
// If it's a request for content, use the networkFirst
// strategy, and send an offline page if both network and
// cache fail.
return toolbox.networkFirst(request, values, options)
.catch(() => {
return caches.match('/offline.html', {ignoreSearch: true});
});
}
}, {
urlPattern: /cdn\.ampproject\.org/,
handler: 'fastest'
}]
};
忘れずにService Woker を再生成しましょう。
sw-precache --config=sw-precache-config.js
動作確認
http://localhost:3000 を開きます。
※ 私の環境だとhttp://localhost:5000 でした
Chromeデベロッパーツールを開き、[Application]タブに移動します。
「Cache」セクションで、「Cache Storage」を右クリックし、「Refresh」をクリックします。
キャッシュをチェックし、ページに必要なファイルがキャッシュにリストされているかどうかを確認します。
[Service Woker]セクションで、[Offline]チェックボックスをクリックし、ページをリロードします。オフラインでもちゃんと読み込まれるはずです。そのまま記事へのリンクの1つをクリックしてください。記事がキャッシュされていないので、カスタムオフラインページが表示されます。
Webマニフェストを追加する
PWAの大きな利点の1つは、ホーム画面に追加できることです。そのためには、アプリケーションにWebマニフェストを追加する必要があります。
これは、この執筆時点で、ホームスクリーンにアプリを追加できるようにするためのマニフェスト属性です:
- ホームスクリーンランチャーに必要な
name
とshort_name
の両方。 -
theme_color
とbackground_color
の両方は、スプラッシュ画面の作成に使用されます。 -
display
はネイティブアプリの見た目と感覚を提供するためにスタンドアロンに設定する必要があります。 - アイコンの最小サイズは192pxです。 アイコンはホーム画面と起動したスプラッシュ画面に必要です。
- ユーザーがホームスクリーンアイコンをクリックしたときに最初に開かれる
start_url
。
Webマニフェストの生成
Webマニフェストを手作業で書くと、エラーを起こしやすいです。この作業に役立つオンラインマニフェストジェネレータがいくつかあります。私たちはhttps://app-manifest.firebaseapp.com/ にあるものを使用してwebマニフェストを生成します。
フォームフィールドに必要な値を入力します。このcodelabでは、以下の値を使用します。
- App Name: AMP PWA Codelab
- Short Name: AMP PWA Codelab
- Theme Color: #00796b
- Background Color: #00796b
- Display Mode: Fullscreen
- Start URL: /index.html
次のステップはアイコンをジェネレーターにアップロードすることです。
ICONボタンをクリックし、workフォルダに移動し、/icons/web_hi_res_512.png
にアイコンをアップロードします。
GENERATE ZIPボタンをクリックして、複数のサイズのアイコンとフルマニフェストをダウンロードできます。
ダウンロードしたzipファイルを展開して、`manifest.josがworkフォルダの直下に来るようにコピーします。
マニフェストファイルを指定する
ブラウザにマニフェストを認識させるには、それぞれのページにリンクさせる必要があります。
linkタグをそれぞれのページのheadタグ内に追加することで完了します。
<link rel="manifest" href="/manifest.json">
start_url
がキャッシュされていることを確認する
ホームスクリーンで動くようにするために必要な最後の条件は、ユーザーがオフラインのときでも、start_urlで参照されるURLを常に使用可能にする必要があることです。
この条件を満たすために、Service Woker がインストールされるときにURLをキャッシュしておき、
さらに、networkFirst
キャッシュ戦略を使用して常に最新のものにする事ができます。
オフラインページと比較すると、index.html
ページはより動的な性質を持つため、別のアプローチを使用してページをプリキャッシュする必要があります。sw-precache
の拡張性を利用します。
sw-precache-config.js
ファイルで、別の設定変数を追加します。
importScripts: ['service-worker-import.js']
これにより、生成されたService Woker へimportScript
callが追加されます。次に、ルートフォルダにservice-worker-import.js
ファイルを作成し、次のコードを追加します。
toolbox.precache(['/index.html']);
インポートされたスクリプトが生成されたService Woker によって呼び出されると、index.html
ページがランタイムキャッシュに追加されます。
こうすることで、以前作成した既存のハンドラでページを使用できるようになります。
Service Woker の更新
sw-precache --config=sw-precache-config.js
動作確認
Chromeデベロッパーツールで、[Application]タブに移動し、[Application]セクションの[Manifest]項目を確認します。マニフェストに含まれる情報は、右側に表示されます。
Extra Credits
index.html
ページはキャッシュされていますが、記事の画像はキャッシュされていないことに気づいたかもしれません。
コンテンツのプリキャッシュすることは可能で、しかしながら動的なindex.html
ページのどの画像がキャッシュされているかを把握することは難しいです。
可能な解決策は、画像のリクエストが不可能なときにオフラインイメージを提供することです。これは読者のエキササイズです(←※ ギャグなのか何か意味があるのかよくわからない)。
AMP as a Canonical PWA
おめでとうございます、最初のAMP as a Canonical PWAを実装しました。
あなたはオフラインのシチュエーションにより強く、静的ファイルと画像のキャッシュによりローディングを最適化され、ホームスクリーンから起動する資格を持つアプリケーションを作りました!
7. App Shell の作成
AMP as a Canonical PWAでほとんどのシチュエーションでは十分ですが、開発者はAMPでまだサポートされていないプッシュ通知やクレデンシャルマネージャAPIなどの機能が必要になるかもしれない。
このようなシチュエーションでは、AMP in a PWAが使えます。
Shellでリクエストを置き換える
まずApp Shellをアプリケーションに追加しましょう。service woker 一度インストールされると、ナビゲーションリクエストをキャッチしてShellで置き換えるため、Service Woker を変更します。
shell.html
をworkフォルダ内に作ります。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<title>AMP => PWA Demo</title>
<style type="text/css">
body{margin:0;padding:0;background:#F5F5F5;font-size:12px;font-weight:300;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif}a{text-decoration:none;color:#000}.header{color:#fff;background:#1976D2;padding:8px 16px;box-shadow:0 2px 5px #999;height:40px;display:flex;align-items:center}.header h1{margin:0 8px 0 0}.header amp-img{margin-right:8px}.header img{margin-right:8px}.header a{color:#fff}.header a:visited{color:#fff}
</style>
</head>
<body>
<header class="header">
<img src="/img/amp_logo_white.svg" width="36" height="36" />
<h1><a href="/">AMP PWA Codelab - PWA</a></h1>
</header>
<div id="amproot">
<!-- AMP Content should appear here! -->
</div>
</body>
</html>
sw-precache-config.js
を更新して、作成したshell.html
をナビゲートリクエストに対応させます。フル設定は次のようになります:
module.exports = {
staticFileGlobs: [
'img/**.*',
'offline.html',
'shell.html',
'js/**.js'
],
runtimeCaching: [{
urlPattern: '*',
handler: (request, values, options) => {
// If this is NOT a navigate request, such as a request for
// an image, use the cacheFirst strategy.
if (request.mode !== 'navigate') {
return toolbox.cacheFirst(request, values, options);
}
return caches.match('/shell.html', {ignoreSearch: true});
}
}, {
urlPattern: /cdn\.ampproject\.org/,
handler: 'fastest'
}],
importScripts: ['service-worker-import.js']
};
メインハンドラが変更され、ナビゲーションリクエストがApp Shellに置き換えられました。
amp-shadow
を使ったAMPの読み込み
この手順では、workフォルダのjs/app.js
ファイルを使用します。
このファイルには、shellに必要な定型コードがすでに含まれています。
例えば、バックエンドからAMPドキュメントをフェッチする方法、およびamp-shadowコンポーネントがロードされたときに実行されるコードのスケジュールを可能にするPromiseが含まれています。
まず、App Shellのheadタグ内にamp-shadow
コンポーネントを追加します。
<!-- Asynchronously load the AMP-Shadow-DOM runtime library. -->
<script async src="https://cdn.ampproject.org/shadow-v0.js"></script>
Shell の一番下にjs/app.js
スクリプトをインポートします。
<script src="/js/app.js" type="text/javascript" defer></script>
次に、app.js
スクリプトを開き、<div id="amproot">
にAMPコンテンツを追加するために必要な変数を設定するコードを追加します。
const ampRoot = document.querySelector('#amproot');
const url = document.location.href;
const amppage = new AmpPage(ampRoot, router);
ampReadyPromise
.then(() => {
amppage.loadDocument(url);
});
元の要求はservice woker によってshell.html
のコンテンツに置き換えられましたが、URLは同じです。
AMP rootに挿入するには、このURLからコンテンツを取得する必要があります。そこで、ampReadyPromise
がURLからコンテンツを解決して読み込むのを待ちます。
loadDocument
メソッドを実装しましょう。前のコードの数行上のプレースホルダーを見つけて書き換えます。
loadDocument(url) {
return this._fetchDocument(url)
.then(document => {
router.replaceLinks(document);
window.AMP.attachShadowDoc(this.rootElement, document, url);
});
}
ドキュメントはURLから取得され、一度解決されたら、ドキュメントにの取得のためにamp-shadow
APIが呼び出されます。
AMPファイルの内容を操作する
App Shell
にAMPページを挿入する場合、開発者はAMPドキュメントのセクションを追加、削除、または変更する必要がありそうです。
フェッチされたドキュメントは通常のDOMドキュメントなので、開発者は必要に応じてそれを操作できます。
下のスニペットでは、ヘッダが既にAppShell に存在し、重複してしまうため、AMPドキュメントからHeader要素を削除しています。
loadDocument(url) {
return this._fetchDocument(url)
.then(document => {
const header = document.querySelector('.header');
header.remove();
router.replaceLinks(document);
window.AMP.attachShadowDoc(this.rootElement, document, url);
});
}
動作確認
http://localhost:3000 を開きます。
最初にページを開くとき、service woker がまだインストールされていないので、ブラウザはAMPページを表示します。
ページをリロードすると、App Shellのバージョンがレンダリングされます。
Service Woker をサポートしないブラウザ
今の実装では、service woker をサポートしていないブラウザでアクセスしたユーザーは、App Shell を体験をすることができません。
幸運なことに、amp-install-serviceworker
はページ上のリンクをShell URLに書き換えるfallback
を提供します。
AMPページで、fallback
属性を含めるようにamp-install-serviceworker
を更新します。
service woker をサポートしていないブラウザを使用しているユーザーがAMPファイル内のリンクをクリックすると、AMPランタイムはそのリンクをShell URLに置き換え、元のURLをフラグメントとして
#href=<元のURL>
というフォーマットで追加する
したがって、/articles/1.html
へのリンクは/shell.html#%2Farticles%2F1.html
になります。
App Shell のコードでこの変更を認識させましょう。コンテンツの正しいURLを見つける方法を追加する
※ /shell.html#%2Farticles%2F1.html
は/shell.html#href=%2Farticles%2F1.html
の間違いかな..?
...
function getContentUri() {
const hash = window.location.hash;
if (hash && hash.indexOf('href=') > -1) {
return decodeURIComponent(hash.substr(6));
}
return window.location;
}
...
const ampRoot = document.querySelector('#amproot');
const url = getContentUri();
const amppage = new AmpPage(ampRoot, router);
ユーザーがservice woker から来ている場合は、URLフラグメントが存在するため、decodeURIComponent
を使用して最終URLを抽出できます。
URLの内容がService Woker に置き換えられていた場合、URLはすでに正しいです。
url変数への代入は、新しいメソッドへの呼び出しで置き換えられます。
壊れたURLの修正
URL書き換えフォールバックを使用することの副作用は、ユーザーがShell 内のリンクをクリックすると、URLバーのURLにフラグメントのShell URLが表示されることです。
ページ履歴APIを使用してそれを修正することができます。
ampReadyPromise.then(() => {
return amppage.loadDocument(url);
})
.then(() => {
if (window.history) {
window.history.replaceState({}, '', url);
}
});
loadDocument Promiseが正常に解決されると、Shell URLを読み込まれたばかりのものに置き換えます。
動作確認
service woker をサポートしていないブラウザを起動します。この記事の執筆時点では、WindowsのエッジとOSXのSafariなどがあります。
http://localhost:3000 を開きます。
最初はAMPページが開かれるはずです。ブラウザで開発者ツールを開いて、ソースコードを確認することで確認できます。
ここで、最初のページのリンクの1つをクリックします。 URLは書き換えられていて、ページはAppShell を使用してレンダリングされているはずです。
おめでとうございます!
初めてのAMP in a PWAの実装が完了しました。あなたのアプリケーションはAMP as a Canonical PWAパターンのすべての利点を持っており、AMPでのみ可能だった機能を追加できるようになりました。
What's Next?
このcodelabは、Progressive Web Apps with AMPを構築するときにできることの表面を引っ掻いただけです。
より複雑な体験を構築する場合は、アプリケーション設計をPWA Checklistと照合して確認してください
また、service woker の仕組みの詳細については、Your First Progressive Web Appを確認してください。