SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

次世代Webアプリケーションフレームワーク「Angular」の活用

AngularのPWA(Progressive Web Apps)機能でアプリのようなWebページを作成

次世代Webアプリケーションフレームワーク「Angular」の活用 第16回

キャッシュによるオフライン表示をサポートするAngularのService Worker

 Service Workerは、Webページと独立してバックグラウンドで動作するJavaScriptです。Angularでは、ネットワーク接続なしでWebページを表示できるService Workerのキャッシュ機能を、より利用しやすくする機能が提供されます。

AngularのService Worker設定

 AngularのService Worker機能は、「@angular/service-worker」パッケージで提供されます。「ng add」コマンドでPWA機能を追加すると、モジュール定義ファイル(app.module.ts)にService Workerの設定が自動的に追加されます。

[リスト5]AngularのService Worker設定(p001-default/src/app/app.module.ts)
import { ServiceWorkerModule } from '@angular/service-worker'; // ...(1)
(略)
@NgModule({
(略)
  imports: [
    BrowserModule,
    ServiceWorkerModule.register('ngsw-worker.js',
      { enabled: environment.production }) // ...(2)
  ],
(略)

 (1)で参照したServiceWorkerModuleを利用して、(2)でService Workerを設定します。この設定では、本番ビルド設定(environment.production)のときだけ、「ngsw-worker.js」というファイル名でService WorkerのJavaScriptを配置します。

 リスト5の設定によって、ngsw-worker.jsがビルド後のファイルに含まれるようになり、Service Workerとして実行されます。開発者が自分でService Workerを実装する必要はありません。

図11:ビルド後のファイルに含まれるngsw-worker.js(p001-default)
図11:ビルド後のファイルに含まれるngsw-worker.js(p001-default)

AngularのService Workerが提供するキャッシュ機能

 PWA機能を追加したAngularのWebアプリでは、Service Workerによって、以下のファイルが自動的にキャッシュされます。そのため、一度Webページを表示してキャッシュしておけば、ネットワーク接続がなくても、同じURLでWebページを再表示できます。

  • index.html
  • favicon.ico
  • ビルドで生成されたJavaScriptやCSSファイル
  • assetsフォルダー配下のファイル(画像ファイルなど)

 なお、Chromeブラウザーでは、F12キーで起動できるデベロッパーツールの「Network」タブで「Offline」をチェックすると、ネットワーク接続がない状態にできます。この状態でページを再読込すると、画面下部の取得ファイル一覧に「from ServiceWorker」と表示されて、Service Workerによるキャッシュが有効になっていることが確認できます。

図12:Chromeブラウザーのデベロッパーツールでキャッシュを確認(p001-default)
図12:Chromeブラウザーのデベロッパーツールでキャッシュを確認(p001-default)

キャッシュの自動更新と手動更新

 Service Workerを利用したキャッシュ機能を開発者が自分で実装する場合、複数ファイルの整合性を保ちながらキャッシュを保持・更新するのは開発者の責任です。それに対してAngularのキャッシュ機能では、キャッシュの管理が自動化されます。Webページのファイル更新を検知すると、整合性を維持しながらキャッシュを更新してくれます。

 更新確認や更新処理は、Webページの表示時に自動で行われますが、別のタイミングで明示的に実行することもできます。図13のサンプルでは、30秒間隔で更新確認をして、更新が見つかったら利用者に更新を促します。

図13:定期的にキャッシュの更新確認を行うWebページ(p003-update)
図13:定期的にキャッシュの更新確認を行うWebページ(p003-update)

 コンポーネントに実装した更新処理はリスト6です。

[リスト6]Angularのキャッシュ更新処理(p003-update/src/app/app.component.ts)
// コンストラクターでSwUpdateのオブジェクトを受け取る ...(1)
constructor(private updates: SwUpdate) {
  // 更新が見つかったときの処理 ...(2)
  this.updates.available.subscribe(event => {
    alert('新しいコンテンツが見つかりました。更新します。');
    this.updates.activateUpdate(); // 更新を実行 ...(3)
  });
  // 更新が完了したときの処理 ...(4)
  this.updates.activated.subscribe(event => {
    alert('コンテンツが更新されました。ページを再読込します。');
    document.location.reload();
  });
  // Service Workerが準備できてから実行 ...(5)
  navigator.serviceWorker.ready.then(() => {
    // 30秒に1回更新確認を行う処理 ...(6)
    setInterval(() => {
      this.updates.checkForUpdate(); // 更新を確認 ...(7)
    }, 30 * 1000);
  });
}

 Angularのキャッシュ更新処理を提供するSwUpdateのオブジェクトupdatesを、(1)のコンストラクターで、依存性注入を利用して受け取ります。

 更新が見つかったときの処理は(2)のupdates.available、更新完了時の処理は(4)のupdates.activatedに、それぞれ記述します。ここでは、更新が見つかったら(3)のupdate.activateUpdateメソッドで更新を実行して、完了したらページを再読込するように実装しています。

 (5)のnavigator.serviceWorker.ready.thenメソッドで、Service Workerの準備ができているのを確認してから、(6)の更新確認処理を開始します。ここでは30秒に1回、(7)のupdates.checkForUpdateメソッドで更新を確認します。

 リスト6の処理を確認するには、WebブラウザーにWebページを表示させたまま、コンポーネントのテンプレートファイルをリスト7のように書き換えたあと、「npm run pwa」コマンドで再ビルド/Webページ公開します。

[リスト7]更新検知を試す書き換え(p003-update/src/app/app.component.html)
<!-- 変更前 -->
<!--
<img src="../assets/images/main_picture_1.jpg" width="480px">
-->
<!-- 変更後 -->
<img src="../assets/images/main_picture_2.jpg" width="480px">

 しばらくすると、リスト6(2)の処理が更新を検知して、確認ダイアログを表示します。(3)の処理で更新を実行して、完了すると(4)の処理でページが再読込されます。

図14:キャッシュの更新を検知したときの動作(p003-update)
図14:キャッシュの更新を検知したときの動作(p003-update)

キャッシュするファイルの設定

 AngularのService Worker機能でキャッシュするファイルは、ngsw-config.jsonファイルで定義されています。デフォルトのngsw-config.jsonファイルをリスト8に示します。

[リスト8]Angularのキャッシュ設定ファイル(p001-default/ngsw-config.json)
{
  "index": "/index.html",
  "assetGroups": [ // キャッシュするファイルのグループ配列 ...(1)
    { // 1つ目のグループ ...(2)
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html",
          "/*.css",
          "/*.js"
        ]
      }
    },
(略:2つ目のassetGroup「assets」)
  ]
}

 キャッシュするファイルは(1)のassetGroupsに設定します。assetGroupsは配列で指定でき、デフォルトではHTML/JavaScript/CSSをキャッシュする「app」という名前のグループ(2)と、assetsフォルダーのファイルをキャッシュする「assets」という名前のグループが登録されています。グループごとに、表2のような設定ができます。

表2 ngsw-config.jsonの設定項目
No. 設定項目  役割    
1 name グループの名前
2 installMode インストール時のファイル取得モード
3 updateMode アップデート時のファイル取得モード
4 resources キャッシュするファイル

 installMode、updateModeは、「prefetch」を指定すると、インストール/アップデート直後にすべてのファイルを取得するようになり、「lazy」では、インストール/アップデート直後にはファイルを取得せず、リクエストを受けてから取得するようになります。そのほか設定項目の詳細は公式ページを参照してください。

まとめ

 本記事では、ネイティブアプリのようなWebページを実現するProgressive Web Apps(PWA)に対応するAngularの機能を説明しました。Angular CLIのコマンドで、アプリ名やアイコンを定義するWeb App Manifestと、キャッシュ機能を実現するService Workerを、AngularのWebページに自動的に追加できます。

 Service Workerを利用すると、Webページにリモートから通知を送り込む、いわゆるプッシュ通知が実現できます。次回記事では、AngularのWebページでプッシュ通知を利用する方法を説明します。

参考資料

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
次世代Webアプリケーションフレームワーク「Angular」の活用連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト  吉川 英一(ヨシカワ エイイチ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/11151 2018/10/30 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー