自分のサイトをサクッとPWA化!PWA導入編①

2019/06/07 2019/06/07 #javascript #PWA #モバイルアプリ #Android

PWAを簡単に導入するには?

最近のWEB言語界隈は流行り廃りが非常に激しいですよね。でもこのPWAはまだまだこれからな技術!導入したい誰かのために、導入方法を簡単ではありますが、記載しておこうと思います。

基礎知識として

ServiceWorkerご存知でしょうか?

このページにはこう記載されています。

Service Worker の紹介
リッチなオフライン体験、定期的なバックグラウンド同期、プッシュ通知など、これまでネイティブアプリを必要としていた機能が Web にもやってきます。 Service Worker はそれらの機能を提供する基盤技術です。

Service Worker とは
Service Worker はブラウザが Web ページとは別にバックグラウンドで実行するスクリプトで、Web ページやユーザーのインタラクションを必要としない機能を Web にもたらします。 既に現在、プッシュ通知やバックグラウンド同期が提供されています。 さらに将来は定期的な同期、ジオフェンシングなども導入されるでしょう。 このチュートリアルで説明する機能は、ネットワーク リクエストへの介入や処理機能と、レスポンスのキャッシュをプログラムから操作できる機能です。

Service Worker はブラウザが Web ページとは別にバックグラウンドで実行するスクリプトで」この一文がキモですよね。
要はWEBページ開いて無くても、バックグラウンドで特定の処理をしてくれるということです。ブラウザ立ち上げてないのにプッシュ通知受け取ってくれたりするのはこの子のおかげです。

manifest.jsonご存じでしょうか?

要はこのWEBアプリの基本属性の情報をためておくファイルですね。
テーマカラーは青で・・・アプリ名は〇〇で・・・アイコンは〇〇.pngで・・・みたいな情報を格納するファイルがmanifest.jsonです。

ちなみにこのサイトのmanifest.jsonは簡単な構成です。

{
    "short_name": "non's Labo",
    "name": "non's Labo",
    "display": "standalone",
    "icons": [{
            "src": "android-chrome-512x512.png",
            "type": "image/png",
            "sizes": "48x48"
        },
        {
            "src": "android-chrome-512x512.png",
            "type": "image/png",
            "sizes": "96x96"
        },
        {
            "src": "android-chrome-512x512.png",
            "type": "image/png",
            "sizes": "192x192"
        }
    ],
    "start_url": "/"
}

それかこっちを見てね。
スクリーンショット 2019-07-14 17.12.23.png

この構成ファイルをもとに、PWAとしてインストールする情報になっています。
上図に乗っているアイコンが、アプリアイコンとして使用され、Name属性がアプリ名として、アイコンの下に表示されます。

導入するにはこの子達の設定をすればいいだけ

  1. 読み込むべきファイルを用意します。
    manifest.json
    {
     "short_name": "non's Labo",
     "name": "non's Labo",
     "display": "standalone",
     "icons": [{
             "src": "android-chrome-512x512.png",
             "type": "image/png",
             "sizes": "48x48"
         },
         {
             "src": "android-chrome-512x512.png",
             "type": "image/png",
             "sizes": "96x96"
         },
         {
             "src": "android-chrome-512x512.png",
             "type": "image/png",
             "sizes": "192x192"
         }
     ],
     "start_url": "/"
    }

sw.js

var urlsToCache = [
    '/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('laboCache')
        .then(function (cache) {
            urlsToCache.map(url => {
                return fetch(new Request(url)).then(response => {
                    return cache.put(url, response);
                });
            })
        })
        .catch(function (err) {
            console.log(err);
        })
    );
}

self.addEventListener('activate', function (e) {
    console.log('ServiceWorker activate')
})

self.addEventListener('fetch', function (event) {})
  1. 導入したいTOPページにこれを記載

    <script>
    // PWA
    window.addEventListener("load", () => {
     if ("serviceWorker" in navigator) {
         navigator.serviceWorker
             .register("/sw.js")
             .then(registration => {
                 console.log("ServiceWorker registered");
                 registration.onupdatefound = function() {
                     console.log("Exist update");
                     registration.update();
                 };
             })
             .catch(error => {
                 console.warn("ServiceWorker error", error);
             });
     }
    });
    </script>
  2. 同様にheadタグ内でmanifest.jsonを読み込み

    <!-- PWA -->
    <link rel="manifest" href="/manifest.json">

解説

sw.jsについて

sw.jsこれはなにかというと、WEBページがアクティブじゃないときに走る処理です。

// インストールされたとき
self.addEventListener('install', function (event) {});
// アクティベートしたとき
self.addEventListener('activate', function (event) {});

など、様々なイベントを検知して、バックグラウンド実行してくれます。
他にもイベントはたくさん用意してありますし、これ用のサードパーティ製ライブラリも存在します。
私達はこれを駆使してオフライン対応や、通知イベントを発火したりします。

上に書かれているような内容ではconsole.logでログ吐き出しているので、オフライン対応もへったくれも無いですね。

PWA導入「ホームボタンへ追加」について

<script>
// PWA
window.addEventListener("load", () => {
    if ("serviceWorker" in navigator) {
        navigator.serviceWorker
            .register("/sw.js")
            .then(registration => {
                console.log("ServiceWorker registered");
                registration.onupdatefound = function() {
                    console.log("Exist update");
                    registration.update();
                };
            })
            .catch(error => {
                console.warn("ServiceWorker error", error);
            });
    }
});
</script>

そのページがロード完了したらserviceWorkerを起動させてregisterでインストール処理を走らせます。クリックされればthenが走ります。
また、このページにアクセスするたびに、registration.onupdatefound でキャッシュのアップデートがないか確認します。ある場合(つまりjavascriptが変更されている場合やcssが変更されている場合)はregistration.update();で更新処理が動作します。これでキャッシュの中身を入れ替えてバージョンを管理しています。
スクリーンショット 2019-07-14 17.30.33.png

登録されればこんなふうになります。(追記:2019-07-13)
スクリーンショット 2019-07-14 17.31.35.png

モバイルの場合(追記:2019-07-13)
スクリーンショット 2019-07-14 17.36.23.png

スクリーンショット 2019-07-14 17.36.41.png

ここに表示されているのが、manifest.jsonの内容ですね。

headで読み込みするのを忘れずに

scriptmanifest.json読み込みできなければ上の図のようなボタンは発生しません。
ご注意を!

最後に

改めて読み返し見ると、わかりにくい箇所が何点かありますね・・・
これは今後記事の更新をしていくとしましょう!
この記事が参考に慣れば幸いです。

のん

名刺 : About me.

YouTube : のんラボ

Twitter : @nonz250

Github : nonz250

Qiita : @nonz250

My Qiita posts My Qiita contributions My Qiita followers

主にPHPを使用し、サーバーサイドを担当。最近はフロントにも興味津々。

なにかを作ったりいじったりするのが好きで、個人開発なども行っている。

趣味はバイクアイコン画像は大抵愛車の「Z250」である。友達にアイコン描いてもらえて嬉しい。

PHP / Laravel / CakePHP2 / CakePHP3 / Vue / Nuxt / C# / etc...

Tags

#のんラボ #Laravel #Vue #個人開発 #ブログ #プログラミング #javascript #Html5 #WEBサービス #Twitter #今年の抱負メーカー #勉強方法 #PWA #モバイルアプリ #Android #ツーリング #バイクに乗るエンジニア #Z250 #秋吉台 #能登半島 #バイク #冒険 #東尋坊 #Squid #リバースプロキシ #hosts #axios #cropper #AdSense #Bootstrap #MySQL #高速化 #トドTask #Telescope #デバッグ #composer #テスト #セキュリティ #POSレジ #スマレジ #本部機能 #バリデーション #入力チェック #Mac #Chrome #テスト駆動開発 #開発手法 #UI #デザイン #WEBサイト #機能美 #PHP #Laravel 6 #コメント #バージョンアップ #vue-cli #localhost #BIツール #売上分析 #TANAX #MFK250 #ツアーシェルケース2 #RESTful #API #REST API #実務的 #PHP Tech Tutor #Smaregi Tech Talk #勉強会 # ブログ #CakePHP3 #CSRF #VSCode #開発環境 #CakePHP3.0 #さくらのレンタルサーバー #モジュールモード #シェル #メール #Gmail #relay #OGP #エラーページ #抱負 #家庭教師 #ドメイン駆動設計 #DDD #読書会 #那智の滝 #伊勢志摩 #伊勢志摩スカイライン #フロント #三方五湖 #レインボーライン #ボーイスカウト・ルール #プログラマが知るべき97のこと #リファクタリング #ユビキタス言語 #車輪の再発明 #マイクロサービス #デプロイ #QA #laravel-mix #Tips #storybook #@storybook/addon-actions #昇降デスク #コードレス #書斎 #オフィス #リモートワーク #働き方 #エラーハンドリング #スマレジ4 #pixel 5 #レビュー #スマレコ #TDD #RSS #404 #高山ダム #ラーツー #React #Nuxt #node_modules #エラー #インポート #設定方法 #環境構築 #Docker #フォレストパーク神野山 #学生向け #PR #採用 #Node.js #npm #しまなみ海道 #youtube #CSS #IE #SLA #Rust #千里浜なぎさドライブウェイ #千里浜 #インサイドセールス #曽爾高原 #無線LAN #ポートフォリオ #バルカンS #納車 #Next.js #チームビルディング #リーダー #悩み #Github Actions #Marp #ネタ #サーバー移行 #S3 #ストレージサーバー #RFC 7807 #Digest #認証 #Xdebug #CLI #西日本 #例外