今更ですが、Angular6 + OnsenUIを使って作ったシンプルなCordovaのAndroidアプリをPWA化してみた時のメモです。もともとRESTなどWebトランザクションは使っていませんので簡単に動くはずという目論見です。CordovaのPluginを一部使っていますが、以下のようなコードで切り分けて、Pluginなしでも動くようにしておきました。
declare var cordova: any;
...
if (cordova) {
....
}
ChromeにLighthouseをインストール
https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk?hl=jから「Chromeに追加」ボタンをクリック。
Chromeの右上に
灯台アイコンが現れたらクリック→「Options」でProgressisve Web Appのみを選択。
既存のプロジェクト名を確認
angular.json
を開いてプロジェクト名を確認
...
},
"defaultProject": "mycordova"
}
@angular/pwaをインストール
アプリのルートフォルダでng --version
でほかのモジュールのバージョンを確認。
Angular CLI: 6.0.8
Node: 8.12.0
OS: win32 x64
Angular: 6.1.7
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.6.8
@angular-devkit/build-angular 0.6.8
@angular-devkit/build-optimizer 0.6.8
@angular-devkit/core 0.6.8
@angular-devkit/schematics 0.6.8
@angular/cli 6.0.8
@angular/platform-server 6.1.10
@ngtools/webpack 6.0.8
@schematics/angular 0.6.8
@schematics/update 0.6.8
rxjs 6.3.2
typescript 2.7.2
webpack 4.8.3
@angular-devkit/architectなどと同じバージョン番号の0.6.8をセレクト。
この選択が良いのか自身がないですが、少なくともバージョン指定なしで最新の@angular/pwaでは動作しないようでした。先ほど確認したProject名を指定。
ng add @angular/pwa@0.6.8 --project mycordova
Installed packages for tooling via npm.
CREATE ngsw-config.json (392 bytes)
CREATE src/assets/icons/icon-128x128.png (1253 bytes)
CREATE src/assets/icons/icon-144x144.png (1394 bytes)
CREATE src/assets/icons/icon-152x152.png (1427 bytes)
CREATE src/assets/icons/icon-192x192.png (1790 bytes)
CREATE src/assets/icons/icon-384x384.png (3557 bytes)
CREATE src/assets/icons/icon-512x512.png (5008 bytes)
CREATE src/assets/icons/icon-72x72.png (792 bytes)
CREATE src/assets/icons/icon-96x96.png (958 bytes)
CREATE src/manifest.json (1073 bytes)
UPDATE angular.json (4732 bytes)
UPDATE package.json (2999 bytes)
UPDATE src/app/app.module.ts (4356 bytes)
UPDATE src/index.html (1065 bytes)
いろいろとファイルを準備してくれる。
app.moduel.tsの確認
src/app/app.module.tsの内容を確認。
以下がでたらめなところに突っ込まれてコードが破壊されていたので、適切な場所に移動。
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
さらに以下を追加。
@NgModule({
...
imports: [
...
ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })
],
src/index.htmlを確認
こちらは以下が追加されていたけど特に問題なし。
...
<link rel="manifest" href="manifest.json">
<meta name="theme-color" content="#1976d2">
...
キャッシュを設定
OnsenUIやCordovaアプリが使用しているリソースをキャッシュする設定に修正。
{
"index": "/index.html",
"assetGroups": [{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/*.css",
"/*.js",
"/*.eot",
"/*.svg",
"/*.ttf",
"/*.woff",
"/*.woff2",
"/images/**"
]
}
}, {
Lighthouseで状態を確認
ここでng build --prod
でビルドしてApacheサーバからChromeで表示。その後、Lighthouseでレポート作成。なお、ng build --watch
ではPWA関連のファイルが準備されないみたい。
これらを順番に解決していく。
Does not redirect HTTP traffic to HTTPS の修正
apacheのhttpd.confの最後に以下のmod_rewriteのHTTPからHTTPSへのリダイレクト設定を追加。
# HTTPをHTTPSにリダイレクトする設定。
<ifModule mod_rewrite.c>
RewriteEngine On
LogLevel alert rewrite:trace3
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</ifModule>
Does not provide fallback content when JavaScript is not available の修正
<body>
<noscript>
Please enable JavaScript to run this application.
</noscript>
noscriptを追加。
Does not provide a valid apple-touch-iconの修正
<link rel="apple-touch-icon" href="assets/icons/icon-192x192.png" />
アイコンへのリンクを追加。
Page load is not fast enough on mobile networksの修正
遅いって言われても。。。アプリにはあまり改良の余地はない。。。
LighthouseのPerformanceを有効にして調査をお願いしてみる。
Enable text compressionが主要因だそうで、Apacheでテキスト圧縮を有効にしてみる。
LoadModule deflate_module modules/mod_deflate.so
LoadModule filter_module modules/mod_filter.so
上記モジュールを有効に。
Apacheのmod_deflateでデータを圧縮して転送量を削減する
を参考にさせていただきます。
<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|ico)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI _\.utxt$ no-gzip
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/atom_xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/x-httpd-php
</IfModule>
何とか合格をいただきました。
ちなみにServiceWorkerなどを含むこの状態で再びCordovaをビルドしても問題なく動作するようです。
参考ページ
Building A PWA Using Angular 6
はじめてのプログレッシブウェブアプリ
apacheでhttpへのアクセスをhttpsへ自動リダイレクトする
Apacheのmod_deflateでデータを圧縮して転送量を削減する
Apacheの使用方法