PWAアプリをネイティブアプリに近づけるためのJavascriptまとめ

PWAアプリをネイティブアプリに近づけることができる、JavascriptのAPIやコードをまとめました。PWAだけに限定されたものではありませんが、PWAでより威力を発揮するものをピックアップしています。

PWAインストール・プロンプトの制御

ネイティブアプリっぽく使ってもらうには、PWAをインストール(ホームに追加)してもらうのが最初の一歩です。

PWAアプリでは、「ユーザーがPWAページに2回以上のアクセスしている、かつそのアクセスに5分以上の間隔がある」という条件で、ホーム画面への追加を促すポップアップがブラウザで表示されますが、PWAのインストールプロンプトは「beforeinstallprompt」イベントをリッスンすることで表示コントロールができます。

function installBtn(){
  let deferredPrompt;

  window.addEventListener('beforeinstallprompt', (e) => {
    e.preventDefault();
    deferredPrompt = e;
    deferredPrompt.prompt();
  });
}

PWAアプリの紹介ページなどを用意して、インストールを促してネイティブアプリと同列に使ってもらいましょう。

Web Share API

ブラウザからOSネイティブのシェアダイアログを呼び出す関数です。

Javascirpt「navigator.share」を呼び出すだけなので、とても簡単に導入できます。

const shareData = {
  title: 'タイトル',
  text: '説明文',
  url: 'URL',
}

if (navigator.share) {
  navigator.share(shareData)
} else {
  if (this.onError) {
    this.onError('Web Share not supported');
  }
}

「navigator.share」については、PWA(Service Worker必須)に限定した機能ではないので、通常ページやAMPページも利用できます。

ページ上でシェア用のボタンを用意するのも良いですが、OSのシェアダイアログを出した方がユーザービリティが高くネイティブアプリっぽくなります。シェアしてもらえる割合も高くなりそうです。

PWAのアップデート(Service Workerの再登録)

PWAで構築したアプリがネイティブアプリと違うのは、ストアを通じたアップデート機能がないことです。

逆に「常に最新」というのがPWAの良いところでもありますが、PWAアプリではService Workerで関連ファイルをキャッシュすることが多く、ブラウザによっては強制リフレッシュでもキャッシュを離してくれないことがあります。

そのため、

  • 一度Service Workerを解除
  • Service Workerを再登録
  • ページリフレッシュ

というフロー実行するスクリプトを仕込んでおくことで、確実にPWAをアップデートすることができます。

window.navigator.serviceWorker.getRegistrations()
.then(registrations => {
  for(let registration of registrations) {
    registration.unregister();
  }
});
window.location.reload(true);

PWAアプリがアップデートによって大幅に機能が変わる際などには、プッシュ通知やページ内ダイアログなどでアップデートを促して、このスクリプトを走らせることで、PWAアプリを強制的に最新版にアップデートできます。

ユーザーデータを永続化するlocalstorage / IndexedDB

PWAアプリが、ネイティブアプリと同様にオフラインでも利用されることを考えると、ユーザーデータの保持にはブラウザの保存領域を使うケースが多くなります。

ブラウザで使える保存領域については、

  • クッキー
  • local storage
  • IndexedDB

があります。

簡単なのがlocal storageで、Javascriptから、

//連想配列で直接保存
localStorage.userName = "hogehoge";

//setItemメソッドで保存
localStorage.setItem("userName", "hogehoge");

このスクリプトを走らせるだけでデータが保存されます。

local storageはブラウザを閉じてもデータが保持されるので、設定データなどの永続化に最適です。

一方で、もっと大きなデータ(マスターデータなど)を保持する場合には、IndexedDBが最適です。

IndexedDB API

NoSQLに似たキー・バリュー型データベースで、「window.indexedDB」でネイティブに呼び出すことができます。local storageと同じく、データはキャッシュをクリアしない限り、永続化します。

Dexie.jsなどのライブラリを使えば、SQLに近い形で使うことができます。

import Dexie from 'dexie'

var db = new Dexie("friend_database");
db.version(1).stores({
    friends: 'name,shoeSize'
});

db.friends.put({name: "Nicolas", shoeSize: 8}).then (function(){
    return db.friends.get('Nicolas');
}).then(function (friend) {
    alert ("Nicolas has shoe size " + friend.shoeSize);
}).catch(function(error) {
   alert ("Ooops: " + error);
});

クッキーについては、リターゲティング機能を中心にどのブラウザについても締め出す方向性なので、あまり使わない方が良いでしょう。


PWAアプリをネイティブアプリに近づけるためのJavascriptを見てきました。

どの機能も簡単に導入できますが、PWAアプリと組み合わせる際は、しっかりとロジックを組んで使う必要がありますが、PWAをよりネイティブアプリに近づけることができる機能なので、積極的に導入したい機能です。