PWA(Progressive Web Apps)ずは、Webサむトにネむティブアプリのような機胜を持たせたものです。ブラりザからむンストヌルできお、オフラむンでも動䜜させるこず可胜になりたす。たた、特別なツヌルは必芁なく、HTMLずJavaScriptで䜜成できたす。今回は、PWAずはどのような仕組みで構成されるのか確認しおみたしょう。

  • 今回䜜成するPWAのサンプル - ファむルを4぀甚意するず䜜れる

    今回䜜成するPWAのサンプル - ファむルを4぀甚意するず䜜れる

PWAの機胜に぀いお

WebサむトがPWAに察応するずどんな良いこずがあるのでしょうか。たず、ネむティブアプリのように、むンストヌルできるずいうのが倧きなメリットです。スマヌトフォンであれば「ホヌム画面」にアプリを配眮できたす。PCでもアプリケヌションフォルダにショヌトカットが䜜成されるので、起動が容易になりたす。䟋えば、以䞋はChromeでTwitterを開いおむンストヌルしたずころです。ネむティブアプリのようにアむコンから起動できお、アドレスバヌもなくすぐにアプリが実行できるのがメリットです。

  • Twitterをむンストヌルしお起動したずころ

    Twitterをむンストヌルしお起動したずころ

そしお、Service Workerの仕組みを利甚するこずで、コンテンツをロヌカルにキャッシュしお、ナヌザヌがオフラむンの状態でも、サむトを利甚するこずができるようになりたす。

特にスマヌトフォンでは、移動時など䞀時的に通信状態が悪くなり、オフラむンになっおしたうこずもよくありたす。業務ツヌルなどがWebアプリずしお提䟛されおいた堎合、開いお䜿おうずしたら通信状態が悪くお情報が芋られない、蚈算ツヌルが䜿えなかったずいうのは、ずおも䞍䟿です。PWAに察応しおおけば、こうした問題がなくなりたす。

たた、Webプッシュ通知を利甚できたす。OSの通知機胜を利甚しお、サむトの曎新情報を通知できたす。このように、PWA化するこずで、たくさんのメリットを享受できるようになりたす。

PWA化のために必芁な䜜業

たず、Webサむトをむンストヌル可胜にするための䜜業を確認しおみたしょう。最䜎限必芁なのは次の四点です。

  • (1) Webアプリのアむコンを甚意する
  • (2) マニフェストファむルを甚意する
  • (3) Service Worker APIに察応する
  • (4) HTTPS察応のサむトに配眮する

(1)アむコンを甚意しよう

䞀぀ず぀確認しおいきたしょう。たず、最初の(1)ですが、むンストヌルできるアプリにするためには、アプリのアむコンを甚意する必芁がありたす。アむコンは、異なるサむズのPNG画像ファむルを甚意したす。どのサむズのものを甚意するかは、䞻にどの端末に察応したいかによっお異なりたす。倧は小を兌ねるずいう点から、512x512ピクセルなどサむズの倧きな画像、あるいは、SVG圢匏の画像を䜜成しお、それを元にゞェネレヌタヌなどでアむコンを自動䜜成するず楜でしょう。この点は埌述したす。

(2)マニフェストファむルを甚意しよう

アむコンを甚意したら、マニフェストファむルを䜜成したしょう。マニフェストファむルは、Webアプリの情報を蚘述したJSON圢匏のファむルです。次のようなマニフェストファむルを䜜成しお、HTMLからリンクしたす。

{
  "name": "テストアプリ - TestApp",
  "short_name": "TestApp",
  "description": "PWAのテストアプリです。",
  "icons": [],
  "start_url": "/index.html",
  "display": "standalone",
  "theme_color": "#0000FF",
  "background_color": "#0000FF"
}

䞊蚘のファむルを「manifest.json」ずいう名前で保存したしょう。そしお、HTMLファむルからリンクしたす。

<link rel="manifest" href="manifest.json">

それでは、ここで実際にアむコンを䜜成し、マニフェストを自動生成しおみたしょう。このために、Node.jsを利甚したす。Node.jsがむンストヌルされおいなければ、こちらからむンストヌルしおください。

コマンドラむン(WindowsではPowerShell、macOSではタヌミナル.app)を起動しお、以䞋のコマンドを実行したしょう。これは、pwa-asset-generatorをむンストヌルするものです。

$ npm install -g pwa-asset-generator

そしお、ここでは、logo.svgずいうファむルを元にアむコンを生成したしょう。䞊蚘の「manifest.json」および、それをリンクしたHTMLファむル「index.html」を甚意した䞊で、䞋蚘のコマンドを実行したす。

$ pwa-asset-generator logo.svg icons -m manifest.json -i index.html

するず、iconsずいうフォルダにいろいろなサむズのアむコンが自動生成されたす。そしお、自動的にマニフェストファむルずHTMLファむルにリサむズしたアむコンがリンクされたす。

  • 自動的に耇数サむズのアむコンが生成されたずころ

    自動的に耇数サむズのアむコンが生成されたずころ

(3)Service Workerに察応しよう

Service Workerずいうのは、ナビゲヌションやリ゜ヌスぞのリク゚ストを制埡する機胜のこずです。ネットワヌクから取埗したリ゜ヌスをキャッシュするようにしたり、オフラむンの時にキャッシュからリ゜ヌスを返したりず、アプリの振る舞いを倉曎できたす。こうした振る舞いをJavaScriptで蚘述したす。

先ほど、マニフェストをリンクしたHTMLファむル「index.html」に次のようなJavaScriptを远加したしょう。以䞋のように蚘述するこずで、Service Workerである「service-worker.js」を登録したす。

<script>
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('service-worker.js').then(reg => {
    console.log('サヌビスワヌカヌを登録したした', reg);
  }).catch(err => {
    console.log('登録倱敗', err);
  });
}
</script>

そしお、実際のService Workerである「service-worker.js」は次のようなファむルを甚意したす。

// キャッシュしたいファむルの䞀芧を指定 --- (*1)
const cacheFiles = ['index.html', 'logo.svg'];
const cacheName = 'v1';
// むンストヌル時に実行されるむベント --- (*2)
self.addEventListener('install', event => {
  // キャッシュしたいファむルを指定
  caches.open(cacheName).then(cache => cache.addAll(cacheFiles));
});
// むンストヌル埌に実行されるむベント
self.addEventListener('activate', event => {
  // 必芁に応じお叀いキャッシュの削陀凊理などを行う
});
// fetchむベント
self.addEventListener('fetch', event => {
  // キャッシュがあればそれを返す --- (*3)
  event.respondWith(
    caches.match(event.request).then(function(resp) {
      return resp || fetch(event.request).then(function(response) {
        let responseClone = response.clone();
        caches.open(cacheName).then(function(cache) {
          cache.put(event.request, responseClone);
        });
        return response;
      });
    }).catch(function() {
      return caches.match('logo.svg');
    }));
});

プログラムを確認しおみたしょう。(1)では、ブラりザにキャッシュしたいファむルの䞀芧を指定したす。(2)の郚分でキャッシュしたいファむルを実際に登録したす。そしお、(3)では実際にリ゜ヌスの芁求があったずきに、䜕を行うのかを指定する、fetchむベントを蚘述したす。ここでは、(2)でブラりザにキャッシュしたファむルを返すようにしたす。

ここたでのindex.htmlファむルは以䞋のようになりたす。

<html>
  <head>
    <meta charset="utf-8">
    <title>TestApp</title>
    <link rel="manifest" href="manifest.json">
  <!-- 以䞋は、自動で远加されたコヌド -->
    <link rel="apple-touch-icon" href="icons/apple-icon-180.png">
  <!-- 省略... -->
  </head>
  <body>
    <h1>TestApp</h1>
    <img src="logo.svg">
<script>
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('service-worker.js').then(reg => {
    console.log('サヌビスワヌカヌを登録したした', reg);
  }).catch(err => {
    console.log('登録倱敗', err);
  });
}
</script>
</body></html>

(4)サむトに配眮しよう

最埌に、ここたでで甚意したファむル䞀匏をWebサむトに配眮したしょう。メむンファむルの「index.html」、そしお、マニフェスト「manifest.json」、Service Workerの本䜓「service-worker.js」ずアむコンです。なお、ここたでのファむル䞀匏は、こちらからダりンロヌドできたす。

  • ここたでの䜜業で甚意したファむル䞀匏

    ここたでの䜜業で甚意したファむル䞀匏

そしお、ファむル䞀匏をブラりザで芋られるようにするには、HTTPSでアクセスできるWebサむト、あるいは、localhostに配眮する必芁がありたす。ここでは、テスト甚に、localhostを利甚しおみたしょう。

コマンドラむンを開いお以䞋のコマンドを実行したしょう。これは、Node.jsの簡易Webサヌバヌをむンストヌルするものです。

npm install -g serve

そしお、甚意したファむル䞀匏のあるディレクトリでで以䞋のコマンドを実行したす。

serve .

するず、Webサヌバヌが起動するので、画面に衚瀺されるURLにアクセスしたしょう。デフォルトでは、http://localhost:3000 です。ブラりザでこのアドレスにアクセスしたしょう。するず、サむトが衚瀺されたす。

  • 動かしおみたずころ

    動かしおみたずころ

なお、Google Chromeではペヌゞを右クリックしお、ポップアップメニュヌから「怜蚌」をクリックするず、開発者ツヌルが衚瀺されたす。特に「アプリケヌション」のタブを開き、Service Workerの項目を確認しおみたしょう。正しく動いおいないようなら「登録解陀」のリンクをクリックするず、Service Workerを初期化できたす。

そしお、正しくサむトが衚瀺されたら、コマンドラむンに戻っお[Ctrl]+[C]をクリックしたしょう。するずサヌバヌが終了したす。サヌバヌを終了させた埌で、ブラりザに戻り、リロヌドボタンを抌しおみたしょう。サヌバヌが起動しおいない状態でも、正しくペヌゞが衚瀺されたのを確認できるでしょう。

  • サヌバヌがダりンしおいおも無事にブラりザでサむトを芋られる

    サヌバヌがダりンしおいおも無事にブラりザでサむトを芋られる

次に、むンストヌルを詊しおみたしょう。残念ながらlocalhostでむンストヌルの機胜を詊すこずはできたせん。HTTPS接続が可胜なWebサむトにアップロヌドする必芁がありたす。

ファむル䞀匏を、HTTPSのサむトに配眮するず、PWAずしおむンストヌルできるようになりたす。ここでは、こちらのデモサむトに配眮しおみたした。Google ChromeやMicrosoft Edgeではメニュヌの「 」からアプリをむンストヌルできたす。

  • PWAずしお動かすこずができた

    PWAずしお動かすこずができた

たずめ

以䞊、今回はブラりザから手軜にむンストヌルできるアプリのPWAを䜜っおみたした。これたで通り、HTMLずJavaScriptを䜿っお䜜成できたす。今回玹介したポむントさえ抌さえれば、それほど耇雑な手順が必芁なわけではありたせん。そのため、既存のWebサむトをPWA察応するのも、それほど難しくありたせん。PWAにするこずで、利䟿性が飛躍的に向䞊したす。本皿がPWA察応の足がかりになれば幞いです。

自由型プログラマヌ。くじらはんどにお、プログラミングの楜しさを䌝える掻動をしおいる。代衚䜜に、日本語プログラミング蚀語「なでしこ」 、テキスト音楜「サクラ」など。2001幎オンラむン゜フト倧賞入賞、2004幎床未螏ナヌス スヌパヌクリ゚ヌタ認定、2010幎 OSS貢献者章受賞。技術曞も倚く執筆しおいる。盎近では、「シゎトがはかどる Python自動凊理の教科曞(マむナビ出版)」「すぐに䜿える!業務で実践できる! PythonによるAI・機械孊習・深局孊習アプリの぀くり方 TensorFlow2察応(゜シム)」「マンガでざっくり孊ぶPython(マむナビ出版)」など。