Compass Project Now a PWA
The full scope of PWA (Progressive Web App) is too much for me to comprehend with my limited web development skills. Fortunately, I don't need to. PWA helper libraries exist, including some tailored to specific web frameworks. Reading over a developer guide for Angular framework's PWA helper, I understood it offers basic PWA service worker functionality without much effort. Naturally, I had to give it a try and see how it turns my Compass project, a simple practice Angular web app, into a PWA.
Following instructions, I ran "ng add @angular/pwa
" in my project and looked over the changes it made. As expected, there were several modifications to configuration JSON files on top of adding one of their own ngsw-config.json
. Eight placeholder icon PNG files (showing the Angular logo) were added to the source tree, each representing a different resolution from 72x72 up to 512x512. Notably, the only TypeScript source code change was in app.module.ts
to register service worker file ngsw-worker.js
, and that service worker file is not part of the source tree where we can enhance it. And if there's an extension mechanism, I don't see it. This tells me behavioral changes are limited to what we can affect via settings in ngsw-config.json
. For app authors that want to go beyond, they'd have to write their own PWA service worker from scratch.
But I don't have any ambition of code changes in this first run. I replaced those placeholder icon PNG files. Change them from the Angular logo to a crude compass I whipped up in a few minutes. Plus a few edits to the application name and cosmetic theme color. (Duplicated in two locations: the .webmanifest
file and in index.html
.) I built the results, deployed to GitHub Pages, and brought it up on my Android phone Chrome browser to see if anything looks different.
Good news: Android Chrome recognized the site is available as a PWA and offered the option to install it. (Adding yet another browser interface bar to the clutter...) I clicked install, and my icon in all its crudeness was added to my Android home screen.
Bad news: I tapped the icon, saw the loading splash screen (with an even bigger version of my crude icon in the middle) and then... nothing. It was stuck at the splash screen.
I killed the app and tried a second time, which was successful: my compass needle came up on screen after a brief pause. (1-2 seconds at most.) I returned to home screen, tapped the icon again, and it came up instantly. Implying the app was suspended and resumed.
A few hours later, I tapped the icon again. It was apparently no longer suspended and no longer available for resume, because I saw the splash screen again and it got stuck again. Killing the app and immediately trying again was successful.
The observed pattern is thus: Initial launch would get stuck at the splash screen due to an undiagnosed issue. Killing the stuck app and immediately relaunching would be successful. Suspend and resume works, but if a suspended app is terminated, we're back to the initial launch problem upon relaunch.
Since it wasn't possible to change any code in @angular/pwa
I'm not sure what I did wrong. Following instructions for "Debugging the Angular service worker" I headed over to the debug endpoint ngsw/state where I saw it couldn't download favicon.ico
from the server. (Full debug output error message below.) I could see the file exists on the server, so I don't understand why this PWA service worker could not download it. At the moment I'm at a loss as to how to diagnose this further. For today I'm going to declare a partial success and move on.
[UPDATE: I've figured it out. By default the PWA service worker assumes the app was deployed to server root, which in this case was incorrect. Since it is hosted at https://roger-random.github.io/compass/
I needed to run "ng deploy --base-href /compass/
"]
Source code for this project is publicly available on GitHub
Appendix
Full error from https://roger-random.github.io/compass/ngsw/state
NGSW Debug Info:
Driver version: 15.2.8
Driver state: EXISTING_CLIENTS_ONLY (Degraded due to failed initialization: Failed to retrieve hashed resource from the server. (AssetGroup: app | URL: /favicon.ico)
Error: Failed to retrieve hashed resource from the server. (AssetGroup: app | URL: /favicon.ico)
at PrefetchAssetGroup.cacheBustedFetchFromNetwork (https://roger-random.github.io/compass/ngsw-worker.js:479:17)
at async PrefetchAssetGroup.fetchFromNetwork (https://roger-random.github.io/compass/ngsw-worker.js:449:19)
at async PrefetchAssetGroup.fetchAndCacheOnce (https://roger-random.github.io/compass/ngsw-worker.js:428:21)
at async https://roger-random.github.io/compass/ngsw-worker.js:528:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9)
Latest manifest hash: ecc53033977c5c6ddfd3565d7c2bc201432c42ff
Last update check: 37s199u
=== Version ecc53033977c5c6ddfd3565d7c2bc201432c42ff ===
Clients:
=== Idle Task Queue ===
Last update tick: 42s670u
Last update run: 37s668u
Task queue:
Debug log:
[37s320u] Error(Failed to retrieve hashed resource from the server. (AssetGroup: app | URL: /favicon.ico), Error: Failed to retrieve hashed resource from the server. (AssetGroup: app | URL: /favicon.ico)
at PrefetchAssetGroup.cacheBustedFetchFromNetwork (https://roger-random.github.io/compass/ngsw-worker.js:479:17)
at async PrefetchAssetGroup.fetchFromNetwork (https://roger-random.github.io/compass/ngsw-worker.js:449:19)
at async PrefetchAssetGroup.fetchAndCacheOnce (https://roger-random.github.io/compass/ngsw-worker.js:428:21)
at async https://roger-random.github.io/compass/ngsw-worker.js:528:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9) Error occurred while updating to manifest 271c8a71bf2acb8075fc93af554137c2e15365f2
[37s229u] Error(Failed to retrieve hashed resource from the server. (AssetGroup: app | URL: /favicon.ico), Error: Failed to retrieve hashed resource from the server. (AssetGroup: app | URL: /favicon.ico)
at PrefetchAssetGroup.cacheBustedFetchFromNetwork (https://roger-random.github.io/compass/ngsw-worker.js:479:17)
at async PrefetchAssetGroup.fetchFromNetwork (https://roger-random.github.io/compass/ngsw-worker.js:449:19)
at async PrefetchAssetGroup.fetchAndCacheOnce (https://roger-random.github.io/compass/ngsw-worker.js:428:21)
at async https://roger-random.github.io/compass/ngsw-worker.js:528:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9) initializeFully for ecc53033977c5c6ddfd3565d7c2bc201432c42ff
[37s110u] Error(Failed to retrieve hashed resource from the server. (AssetGroup: app | URL: /favicon.ico), Error: Failed to retrieve hashed resource from the server. (AssetGroup: app | URL: /favicon.ico)
at PrefetchAssetGroup.cacheBustedFetchFromNetwork (https://roger-random.github.io/compass/ngsw-worker.js:479:17)
at async PrefetchAssetGroup.fetchFromNetwork (https://roger-random.github.io/compass/ngsw-worker.js:449:19)
at async PrefetchAssetGroup.fetchAndCacheOnce (https://roger-random.github.io/compass/ngsw-worker.js:428:21)
at async https://roger-random.github.io/compass/ngsw-worker.js:528:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9
at async https://roger-random.github.io/compass/ngsw-worker.js:519:9) Error occurred while updating to manifest 271c8a71bf2acb8075fc93af554137c2e15365f2