React JSを使用した【PWA】化の構築方法

 React JSを使用したPWA化の構築

GoogleProgressive Web App(PWA)という新しいテクノロジーを提供しました。

PWAテクノロジーは市場に出回ってからしばらく経ちますが、その人気はここ数年で急上昇しております。

PWA開発の基本と定義を見ていきましょう。

PWAとは?

PWA(Progressive Web App)は、Webアプリケーションとネイティブアプリケーションの利点を組み合わせたアプリケーションであり、ハードウェア機能を含めたクロスプラットフォームアプリを提供します。

PWAは、ネイティブアプリよりも開発とサポートが迅速で、低コストであるため、注目されています。

この技術は、モバイルアプリとWebサイトの両方で最高のユーザーエクスペリエンスを提供するように設計されており、有名なクロスプラットフォームアプリには、「Twitter」、「Alibaba」、「Tinder」、「Uber」、「Instagram」、「Aliexpress」などがあります。

TwitterのPWAは、React NativeのWeb版である「react-native-web」で作られており、ユーザーはWebブラウザから直接アプリを開くことができます。

さらに、Webアプリをインストールすることで、ネイティブアプリと同じように、オフラインで利用可能なほぼすべての機能を使用することができます。

PWAは、Webサイトをモバイル、タブレット、ラップトップ、PCなどのインストール可能なアプリケーションに変換することができます。

これにより、ユーザーはアプリをインストールすることなく、Webブラウザから直接アクセスすることができ、ユーザーの利便性が向上します。

PWAは、オフラインで動作することができ、アプリを再び開いたときに前回の状態に復元することもできます。

この機能により、PWAは、低速または不安定なネットワーク環境での利用に適しています。

総じて、PWAは、ネイティブアプリとWebアプリの利点を組み合わせたアプリであり、低コストで迅速に開発およびサポートすることができ、最高のユーザーエクスペリエンスを提供することができます。

PWAで構築する理由

近年、企業はPWAの採用によって大きな成功を収めています。

WebアプリケーションをPWAに変換することで、多くの利点が得られ、ユーザーはアプリケーションをよりスムーズに操作できるようになります。

まずは速度についてです。

PWAを利用したWebアプリは、通常のWebアプリよりも高速です。

これは、すべてのWebページがキャッシュされるため、ユーザーが再度アクセスした際の読み込み時間が短縮されるためです。

また、HTTPSを使用し、安全なオリジン接続から読み込まれるため、アプリの読み込み時間が短縮されます。

次に、インストールについてです。

PWAはダウンロードが速く、ネイティブアプリよりもインストールが早いです。

ネイティブアプリには、App StoreGoogle Play Storeからのダウンロードが必要な場合があり、ユーザーはアプリのインストール、アカウント作成、準備に時間を費やす必要があります。

一方でPWAのWebアプリは、ストアからダウンロードする必要がなく、ユーザーはボタンをクリックするだけでアプリをデバイスに保存できます。

さらに、ブラウザではなくスタンドアロンウィンドウとして実行できるため、ユーザーのホーム画面から起動できます。

バイスのメモリを節約し、ユーザーがアプリを開いたときにのみコンテンツを読み込むことができます。

最後に、オフラインについてです。

通常のWebアプリは、オンラインで動作するように設計されており、インターネット接続が切断されると数分間遅くなる可能性があります。

しかし、PWAはデータを事前にキャッシュしており、インターネット接続の有無にかかわらずWebサイトのコンテンツにアクセスできます。

これは「Service Worker」があるためで、PWAのWebアプリはオフラインでも動作できます。

Service Workerは、PWAのWebアプリから新しいコンテンツをキャッシュし、それをローカルの変更としてリモートサーバーに同期するために役立ちます。

「Service Worker」のキャッシュに関しては、後程詳しく解説致します。

PWAのWebアプリを開発するには、「React.js」や「Angular.js」などのいくつかのJavaScriptフレームワークから1つを選択する必要があります。

特に、「React.js」と「Angular.js」が最も人気のあるフレームワークとなっています。

React.jsはFacebookによって開発されたJavaScriptライブラリであり、仮想DOMを使用してWebアプリを高速にレンダリングできます。

Reactは、PWAアプリケーションを開発するための最適なフレームワークの1つとなっています。

Angular.jsはGoogleによって開発されたJavaScriptフレームワークであり、単一ページアプリケーション(SPA)の開発を容易にします。

Angular.jsは、PWAアプリケーションの開発においても優れたパフォーマンスを発揮します。

PWAは、高速で安全なWebアプリケーションを開発するための優れた選択肢であり、ユーザーの利便性を向上させるためには欠かせないものとなっています。

ReactでPWA Webアプリ作成

シンプルなReactアプリをセットアップします。

当記事では、CRAツールを使用します。

CRAのデフォルトをそのままPWA化しビルドしていきます。

ReactでPWAを作成する方法がわからない人にとって非常に便利な環境です。

組み込みのBabelとWebpackで最新のJavaScript機能を使用できます。

npmを使用すると、PWAコードパッケージに基づいて、すぐにコードを書き始めることができます。

npx create-react-app react-pwa --template cra-template-pwa 

TypeScriptの方は下記となります。

npx create-react-app --template cra-template-pwa-typescript

『create-react-app cra-pwa』コマンドは、react-pwaという名前のアプリを作成します。

『--template cra-template-pwa 』を追加して、Service Workerでアプリを作成します。

※注: CRA 4以降のバージョンでは、組み込みのサービスワーカーは提供されませんのでご注意下さい。

初期のフォルダ構造は下記のようになります。

/📁react-pwa
 ├📁node_modules
        ├依存関係
/📁public
 ├ favicon.io
 ├ index.html
 ├ logo192.png
 ├ logo512.png
 ├ manifest.json
 ├ robots.txt
/📁src
 ├ App.css
 ├ App.js
 ├ App.test.js
 ├ index.css
 ├ index.js
 ├ logo.svg
 ├ reportWebVitals.js
 ├ service-worker.js
 ├ serviceWorkerRegistration.js
 ├ setupTests.js
.gitignore
package.look.json
package.json
     

まずは、『http://localhost:3000』を開いてブラウザで表示の確認をして下さい。

Manifest.json

{
  "short_name": "React App",
  "name": "Create React App Sample",
  "icons": [
    {
      "src": "favicon.ico",
      "sizes": "64x64 32x32 24x24 16x16",
      "type": "image/x-icon"
    },
    {
      "src": "logo192.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "logo512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "start_url": ".",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff"
}

manifest.jsonファイルは、アプリケーションがユーザーとそのインターフェースにどのように表示されるかを制御します。

CRAには、どのスマートフォンでも動作するPWAの構成がほとんどなく、インストールポップアップ構成もありません。

そのため、Service Workerだけを登録してもアプリはスマートフォンにインストールされません。

ですので自分で設定をしていく必要があります。

ReactでPWAをカスタマイズ可能です。

"short_name": "React App",
  "name": "Create React App Sample",

例えば、下記のようにします。

 "short_name": "My PWA",
  "name": "My PWA",

アプリに名前を付ける事ができました。

少なくともshort_nameまたはnameプロパティを指定する必要があります。

両方が指定されている場合、short_nameは、ユーザーのホーム画面、ランチャー、またはスペースが限られている可能性があるその他の場所で使用されます。

nameは、アプリのインストールプロンプトで使用されます。

short_nameはホーム画面の短い名前です。

start_urlはアプリを開いたときに開始するインデックスドキュメントになります。

background_colorはアプリケーションのデフォルトの背景として使用される色で、インストール時およびスプラッシュスクリーンで使用されます。

displayはアプリの表示方法です。

theme_colorはOSで使用される UIのメインカラーです。

iconsでは、ユーザーがサイトをホーム画面に追加するときに、ブラウザが使用する一連のアイコンを定義できます。

それらのアイコンは、ホーム画面、アプリ ランチャー、タスクスイッチャー、スプラッシュスクリーンなどで使用されます。

"icons": [
  {
    "src": "/images/icons-192.png",
    "type": "image/png",
    "sizes": "192x192"
  },
  {
    "src": "/images/icons-512.png",
    "type": "image/png",
    "sizes": "512x512"
  }
]

iconsは画像オブジェクトの配列で、各オブジェクトにはsrcsizesプロパティ、および画像のtypeが含まれている必要があります。

独自のアイコンを拡大縮小してピクセル単位で調整する場合は、アイコンを48dp単位で指定します。

このWebアプリManifestは、ブラウザにWebアプリケーションと、ユーザーのモバイルデバイスまたはデスクトップに『インストール』されたときの動作方法を伝える単純なJSONファイルです。

Chromeで [ホーム画面に追加]のプロンプトを表示するには、Manifestが必要となります。

一般的なManifestファイルには、アプリ名、アプリが使用するアイコン、start_url起動時の開始時刻などに関する情報が含まれております。

ですので、本質的にはアプリに関するメタデータとなっています。

manifestファイルの定義が完了したら、index.html<head>内に追加しましょう。

HTMLファイルであるpublic/index.htmlには、manifestを読み込むための<link>要素も含まれています。

<!--index.html-->

<head>
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />

</head>

CRAでは、/public/index.htmlの親パスは%PUBLIC_URL%を表すため、すべての静的ファイル、画像、またはアイコンに含める必要があります。

そうしないと、どのアセットもインポートされません。

例えばアイコンの場合、WindowsiPhone は、基本構成のPWAを完全にはサポートしていないため、WindowsiPhoneでアプリを機能させるには、メタダクを追加する必要があります。

 <!--iPhone-->

<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-title" content="My App">
<link rel="apple-touch-icon" href="%PUBLIC_URL%/icon.png">
<link rel="apple-touch-icon" sizes="152x152" href="%PUBLIC_URL%/icon/icon-192x192.png">
<link rel="apple-touch-icon" sizes="180x180" href="%PUBLIC_URL%/icon/icon-192x192.png">
<link rel="apple-touch-icon" sizes="167x167" href="%PUBLIC_URL%/icon/icon-192x192.png">

<!--Windows-->

<meta name="msapplication-TileImage" content="%PUBLIC_URL%/icon/icon-144x144.png">

ですがSafari ブラウザではスプラッシュスクリーンが表示されないため、iPhoneのサイズごとにカスタムスプラッシュスクリーンを作成し、メタタグを Safariブラウザに追加する必要があります。

<link href="%PUBLIC_URL%/icon/splashscreens/iphone5_splash.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)" rel ="apple-touch-startup-image" />

この辺りはまた別途記事に致します。

本日は、アプリの名前のみを編集しビルドしていきましょう。

アプリのビルド

コマンドを実行します。

npm run build

アプリケーションが正常に作成されます。

アプリケーションが正常にインストールされたかどうかを確認するには、ブラウザが必要です。

コマンドを実行します。

npm i http-server -D

これは、package.jsonファイルのscriptsにhttp-serverがありますのでご確認下さい。

"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"start-sw": "http-server ./build" // 追加
},

スクリプトコマンドがない場合、新しく追加して下さい。

Service Workerの登録

ReactでPWAを作成するには、「Service Worker」という「Web Worker」を利用します。

「Service Worker」は、Webサイトとは別にバックグラウンドで実行されるスクリプトであり、ページのキャッシュやAPI呼び出しのキャッシュ、プッシュ通知、バックグラウンド同期など、さまざまなことにアクセスすることができます。

先程のCRAで作成したプロジェクトのディレクトリには、「index.js」というファイルがあります。

// index.js

import React from 'react';
import { createRoot } from 'react-dom/client';
import 'index.css';
import App from './App';
import * as  serviceWokerRegistration from './serviceWokerRegistration';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
<React.ScriptMode>

<App />

</React.ScriptMode>
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

Service Workerはまだ登録されていません。

unregister()呼び出しをregister()に変更しなければいけません。

// index.js

import React from 'react';
import { createRoot } from 'react-dom/client';
import 'index.css';
import App from './App';
import * as  serviceWokerRegistration from './serviceWokerRegistration';
import reportWebVitals from './reportWebVitals';



const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
<React.ScriptMode>

<App />

</React.ScriptMode>
);

serviceWokerRegistration.register();
//変更

reportWebVitals();

上記のコードでは、「serviceWorkerRegistration.register()」を呼び出すことで、「Service Worker」を登録しています。

この「Service Worker」は、オフラインでも動作するようにキャッシュを管理するために利用されます。

「Service Worker」のキャッシュの仕組みについて説明します。

「Service Worker」は、キャッシュストレージを持っており、Webアプリが要求するリソース(HTML、CSSJavaScript、画像など)をキャッシュに保存します。

次に同じリソースが要求された場合は、「Service Worker」はキャッシュからリソースを返します。

これにより、オフラインでもキャッシュに保存されたリソースを利用してWebアプリを表示することができます。

また、「Service Worker」は、オンラインになったタイミングでバックグラウンドでキャッシュの更新を行います。

これにより、最新のリソースをキャッシュに保存することができます。

それでは、Reactアプリを改めてビルドし、「serve」を利用してローカルサーバーを起動します。

npm run build 

npm run start-sw

PWAは、デスクトップでもインストールすることができます。インストールすることで、ブラウザを起動することなく、PWAを起動することができます。

先程も述べたように、PWAをデスクトップにインストールするには、ブラウザのツールバーにある「インストール」または「+」アイコンをクリックします。

その後、ポップアップが表示されるので、「インストール」をクリックします。

PWA化のデモ

すると、デスクトップにPWAのショートカットが追加され、クリックすることでPWAを起動することができます。

アプリのビルドが完了したら、Googleが提供するPWAチェックリストやLighthouseツールを使用して、アプリをテストできます。

Lighthouseツールは、Chrome DevToolsのタブにあります。

Lighthouseタブに移動し、「Generate a Lighthouse report」をクリックして、「Generate Report」または「Analyze page state」を選択してください。

これにより、アプリがPWAであることが検出されます。

また、「Control+Shift+J」(MacではCommand+Option+J)を押して、DevToolsを開き、「Application」タブの「Service Worker」タブで、「service-worker.js」ファイルが表示されていることを確認してください。

キャッシュストレージに移動して、キャッシュメモリに保存されているファイルを確認することもできます。

最後に、生成されたレポートを段階的に見ていくと、まだ改善すべき点があるかもしれないことがわかります。

これで、CRAが正常にPWAに変換され、AndroidiOSWindowsなどのデバイスでサポートされるようになりました。

最後に

ReactはPWAの開発を容易にし、PWAはReactをより効果的かつ強力にします。

両方のテクノロジーを使用するアプリは、開発がはるかに簡単になり、より強力で高速となります。

当記事が、Reactを使用し独自のPWA Webアプリを作成するのに役立つことを願っています。

本日は以上となります。

最後まで読んで頂きありがとうございます。

この記事が役に立ったら、ブックマークして他の方にも共有して頂けると幸いです。

プライバシーポリシー

© 2023 Icons8 LLC. All rights reserved.

© [deve.K], 2023. React logo is a trademark of Facebook, Inc. JavaScript is a trademark of Oracle Corporation and/or its affiliates. jQuery and the jQuery logo are trademarks of the JS Foundation. TypeScript and the TypeScript logo are trademarks of the Microsoft Corporation. Next.js and the Next.js logo are trademarks of Vercel, Inc. Firebase and the Firebase logo are trademarks of Google LLC. All logos edited by [deve.K].