Und zack...PWA
Da ist es passiert. Mein Phoenix - die Buchungsverwaltung für Kunden von Phoenix Reisen - ist seit heute eine PWA ("Progressive Webapp"). Zum vorzeigen gibt's allerdings nix, da sich alles after login abspielt. ¯\_(ツ)_/¯
Deshalb nachfolgend nur ein abstraktes "was bisher geschah"...
Zunächst hat die App einen Service Worker bekommen. Um mir einiges an pain in the ass zu sparen, basiert dieser direkt auf Workbox. Nicht zuletzt, da Workbox während eines Aufrufs viele nützliche Infos auf der Konsole ausgibt. Die Strategie ist eine Mischung aus allem.
- Images werden
cache first
ausgehändigt - Code gibt's via
stale while revalidate
- alles andere wird
network first
aufgelöst
Selbstredend gibt's auch ne valide manifest.json
dazu, damit das Ganze standalone
laufen kann.
Dann fehlt auch eigentlich schon nicht mehr viel, außer ihn in jedem (autarken) Frontend zu initialisieren. Gar nicht so schwer. Einfach im bootstrap
-Teil folgende Funktion aufrufen & fertig ist die Laube.
const initServiceWorker = () => {
if('serviceWorker' in navigator) {
window.addEventListener('load', () => {
try {
navigator.serviceWorker.register('./service-worker.js');
} catch(error) {
Sentry.captureException(error);
}
}, false);
window.addEventListener('online', () => {
User.online = navigator.onLine;
m.redraw();
}, false);
window.addEventListener('offline', () => {
User.online = navigator.onLine;
m.redraw();
}, false);
window.addEventListener('beforeinstallprompt', e => {
Config.appInstallPrompt = e;
m.redraw();
}, false);
window.addEventListener('appinstalled', () => {
Config.appAlreadyInstalled = true;
m.redraw();
}, false);
}
}
Wie man in der manifest.json
sieht, ist die start_url
nicht auf das Login-Frontend, sondern auf das Frontend der Übersicht dahinter festgelegt. Deshalb wird man bei einem Besuch der Loginseite nicht gefragt, ob man Mein Phoenix installieren möchte.
Hinter dem Login allerdings, auf der Übersichtsseite, kommt sie dann schließlich aber, die Frage aller Fragen. Einerseits (zum Beispiel) von Android Chrome selbst, andererseits aber auch durch eine selbstgebastelte Installbox, in der ich mir den beforeinstallpromp
Event zunutze mache. Der lässt sich nämlich, wie im obigen Code-Beispiel zu sehen, zwischenspeichern und anschließend bei Bedarf - sagen wir bei einem Button Click - wieder aufrufen. Das sieht auf dem Desktop dann ziemlich ungefähr so aus:

Funktioniert auf meinem Pixel 3 recht super, genauso auf meinem Mac. Da die App komplett #JAMstacked ist und die getätigten REST API Calls
ebenfalls alle gecacht werden, läuft die App schneller als die Konkurrenz erlaubt.
Natürlich ist das grundsätzlich erst der Anfang.
Hiermit sind die Weichen für push notifications
und Offline-Fähigkeit
gestellt.
Ein bisschen üfflein
ist auch schon drinnen: verliert der Gast seine Internetverbindung, erscheint ein dramatisch rotes Hinweis-Overlay, das ihm diesen Umstand mitteilt & die App nur noch eingeschränkt funktioniere - zumindest aber sieht er weiterhin die App und nicht die kalte, unpersönliche Offline-Seite des Browsers. Grundsätzlich kann er sich sogar weiterhin auf allen bisher aufgerufenen (und damit gecachten) Seiten bewegen, solange er nur readonly
unterwegs ist. Sonst gibt's bisher nen Fehler.