Was das Bulletin-Team bei der Entwicklung einer PWA über Servicemitarbeiter gelernt hat.
Esta es la primera de una serie de publicaciones de Blog sobre las lecciones que aprendió el equipo de Google Bulletin al crear una PWA externa. En estas publicaciones compartiremos algunos de los desafíos que enfrentamos, los enfoques que tomamos para superarlos y consejos generales para evitar trampas. Esta no es de ninguna manera una descripción general completa de las PWA. El Ziel es compartir los aprendizajes de la experiencia de nuestro equipo.
In diesem ersten Beitrag werden wir zunächst einige allgemeine Informationen behandeln und dann auf alles eingehen, was wir über Servicemitarbeiter gelernt haben.
Das Bulletin wurde 2019 wegen mangelnder Produkt- / Marktanpassung geschlossen. Unterwegs haben wir noch viel über PWAs gelernt!
Hintergrund
Das Bulletin befand sich von Mitte 2017 bis Mitte 2019 in aktiver Entwicklung.
Warum wir uns für den Bau einer PWA entschieden haben
Bevor wir uns mit dem Entwicklungsprozess befassen, wollen wir untersuchen, warum das Erstellen einer PWA eine attraktive Option für dieses Projekt war:
- Fähigkeit, schnell zu iterieren. Besonders wertvoll, da das Bulletin in mehreren Märkten getestet werden würde.
- Einzelne Codebasis. Nuestros usuarios se dividieron aproximadamente en partes iguales entre Android e iOS. Una PWA significaba que podíamos crear una única aplicación Netz que funcionara en ambas plataformas. Esto aumentó la velocidad y el impacto del equipo.
- Actualizado rápidamente e independientemente del comportamiento del Nutzername. PWAs können automatisch aktualisiert werden, wodurch die Anzahl veralteter Clients in freier Wildbahn verringert wird. Mit einer sehr kurzen Migrationszeit für Kunden konnten wir wichtige Änderungen am Backend vornehmen.
- Es lässt sich problemlos in Ihre eigenen Anwendungen und Anwendungen von Drittanbietern integrieren. Tales integraciones eran un requisito para la aplicación. Con una PWA, a menudo significaba simplemente abrir una Url.
- Die Reibung bei der Installation einer App wurde beseitigt.
Unser Rahmen
Für Bulletin verwenden wir Polymer, aber jedes moderne, gut unterstützte Framework wird es tun.
Was wir über Servicemitarbeiter gelernt haben
Sie können keine PWA ohne eine haben Servicemitarbeiter. Los trabajadores de servicios le brindan mucho poder, como estrategias avanzadas de almacenamiento en Zwischenspeicher, capacidades fuera de línea, sincronización en segundo plano, etc. Si bien los trabajadores de servicios agregan algo de complejidad, descubrimos que sus beneficios superan la complejidad adicional.
Generieren Sie es, wenn Sie können
Vermeiden Sie es, ein Service Worker-Skript von Hand zu schreiben. Das manuelle Schreiben von Servicemitarbeitern erfordert das manuelle Verwalten zwischengespeicherter Ressourcen und das Umschreiben der Logik, die den meisten Servicemitarbeiterbibliotheken gemeinsam ist, z Arbeitsbox.
Aufgrund unseres internen Tech-Stacks konnten wir jedoch keine Bibliothek zum Generieren und Verwalten unserer Servicemitarbeiter verwenden. Unsere folgenden Erkenntnisse werden dies manchmal widerspiegeln. Weitere Informationen finden Sie unter Probleme für nicht generierte Servicemitarbeiter.
Nicht alle Bibliotheken sind mit Servicemitarbeitern kompatibel
Einige JS-Bibliotheken gehen davon aus, dass sie nicht wie erwartet funktionieren, wenn sie von einem Servicemitarbeiter ausgeführt werden. Zum Beispiel unter der Annahme Fenster
oder Dokument
están disponibles, o usando una API no disponible para los trabajadores del servicio (XMLHttpRequest
, lokaler Speicher usw.). Stellen Sie sicher, dass die für Ihre Anwendung erforderlichen kritischen Bibliotheken von Servicemitarbeitern unterstützt werden. Für diese spezielle PWA wollten wir verwenden
gapi.js para la autenticación, pero no pudieron hacerlo porque no admitía a los trabajadores del servicio. Los autores de bibliotecas también deben reducir o eliminar suposiciones innecesarias sobre el contexto de JavaScript siempre que Sein posible para respaldar los casos de uso de trabajadores de servicios, como evitar API incompatibles con trabajadores de servicios y evitar el estado global.
Vermeiden Sie den Zugriff auf IndexedDB während der Initialisierung
Nicht lesen IndexedDB Während Sie Ihr Service Worker-Skript initialisieren, geraten Sie möglicherweise in diese unerwünschte Situation:
- Der Benutzer hat eine Webanwendung mit IndexedDB (IDB) Version N.
- Eine neue Webanwendung ist in der N + 1-Version der IDB enthalten
- Der Benutzer besucht PWA, wodurch der Download eines neuen Servicemitarbeiters ausgelöst wird
- Der neue Servicemitarbeiter liest vor der Registrierung aus der IDB
Installieren
Ereignishandler, der einen BID-Aktualisierungszyklus aktiviert, um von N nach N + 1 zu gelangen - Dado que el usuario tiene un Klient antiguo con la versión N, el proceso de actualización del trabajador del servicio se bloquea ya que las conexiones activas todavía están abiertas a la versión anterior de la base de datos
- Der Servicemitarbeiter hängt und wird nie installiert
In unserem Fall ist der Cache bei der Installation des Service Workers ungültig. Wenn der Service Worker also nie installiert wurde, haben die Benutzer die aktualisierte Anwendung nie erhalten.
Mach es hart
Aunque los Skripte de los trabajadores de servicios se ejecutan en segundo plano, también se pueden finalizar en cualquier momento, incluso cuando se encuentran en medio de operaciones de E / S (red, IDB, etc.). Cualquier proceso de larga duración debería poder reanudarse en cualquier momento.
En el caso de un proceso de sincronización que cargó archivos grandes al Server y se guardó en el BID, nuestra solución para las cargas parciales interrumpidas fue aprovechar el sistema reanudable de nuestra biblioteca de carga interna, guardando la URL de carga reanudable en el BID antes de cargar y usar esa URL para reanudar una carga si no se completó la primera vez. Además, antes de cualquier operación de E / S de larga duración, el estado se guardaba en IDB para indicar en qué parte del proceso estábamos para cada registro.
Hängen Sie nicht vom globalen Staat ab
Da Servicemitarbeiter in einem anderen Kontext existieren, sind viele Symbole, die Sie möglicherweise erwarten, nicht vorhanden. Ein Großteil unseres Codes lief auf beiden Fenster
Kontext sowie einen Service Worker-Kontext (wie Registrierung, Flags, Synchronisierung usw.). Der Code sollte gegenüber den von Ihnen verwendeten Diensten, wie z. B. lokalem Speicher oder Cookies, defensiv sein. Sie können verwenden
globalThis
auf das globale Objekt in einer Weise zu verweisen, die in allen Kontexten funktioniert. Verwenden Sie auch in globalen Variablen gespeicherte Daten sparsam, da nicht garantiert werden kann, wann das Skript beendet und der Status gelöscht wird.
Lokale Entwicklung
Ein wichtiger Bestandteil der Servicemitarbeiter ist das lokale Zwischenspeichern von Ressourcen. Während der Entwicklung ist dies jedoch die Gegenteil als Sie möchten, insbesondere wenn Aktualisierungen träge durchgeführt werden. Sie möchten den Server Worker weiterhin installieren, damit Sie Probleme damit debuggen oder mit anderen APIs wie Hintergrundsynchronisierung oder Benachrichtigungen arbeiten können. In Chrome können Sie dies über Chrome DevTools erreichen, indem Sie die Option aktivieren Bypass für Netzwerk KontrollkästchenAnfrage Panel> Servicemitarbeiter Panel) zusätzlich zur Aktivierung der Cache deaktivieren Kontrollkästchen in der Netz panel para deshabilitar también la memoria caché. Para cubrir más Browser, optamos por una solución diferente al incluir una marca para deshabilitar el almacenamiento en caché en nuestro trabajador de servicio, que está habilitado de forma predeterminada en las compilaciones de desarrolladores. Esto asegura que los desarrolladores siempre obtengan sus cambios más recientes sin problemas de almacenamiento en caché. Es importante incluir el Cache-Kontrolle: kein Cache
encabezado también para evitar que el Browser almacene en caché cualquier activo.
Leuchtturm
Leuchtturm proporciona una serie de herramientas de depuración útiles para las PWA. Escanea un sitio y genera informes que cubren PWA, rendimiento, Barrierefreiheit, SEO y otras mejores prácticas.
Wir empfehlen Lighthouse in kontinuierlicher Integration ausführen um Sie wissen zu lassen, wenn Sie keines der Kriterien für eine PWA erfüllen. Dies ist uns tatsächlich einmal passiert, als der Servicemitarbeiter nicht installiert hat und wir vorher keinen Produktionsschub bemerkt haben. Lighthouse als Teil unseres CI zu haben, hätte dies verhindert.
Umfassen Sie kontinuierliche Lieferung
Da Servicemitarbeiter automatisch aktualisieren können, können Benutzer Aktualisierungen nicht einschränken. Dies reduziert die Anzahl veralteter Kunden in freier Wildbahn erheblich. Als der Benutzer unsere App öffnete, bediente der Servicemitarbeiter den alten Kunden, während er den neuen Kunden träge herunterlud. Sobald der neue Client heruntergeladen wurde, wird der Benutzer aufgefordert, die Seite zu aktualisieren, um auf neue Funktionen zugreifen zu können. Selbst wenn der Benutzer diese Anforderung ignorierte, erhielt er beim nächsten Aktualisieren der Seite die neue Version des Clients. Infolgedessen ist es für einen Benutzer ziemlich schwierig, Aktualisierungen auf die gleiche Weise wie für native Anwendungen abzulehnen.
Mit einer sehr kurzen Migrationszeit für Kunden konnten wir wichtige Änderungen am Backend vornehmen. Wir geben den Benutzern in der Regel einen Monat Zeit, um auf neuere Clients zu aktualisieren, bevor größere Änderungen vorgenommen werden. Da die Anwendung veraltet funktionieren würde, könnten ältere Clients in freier Wildbahn existieren, wenn der Benutzer die Anwendung längere Zeit nicht geöffnet hätte. Unter iOS sind Servicemitarbeiter
nach ein paar Wochen vertrieben
por lo que este caso no sucede. Para Android, este problema podría mitigarse si no se publica mientras está obsoleto o si el Inhalt caduca manualmente después de algunas semanas. En la práctica, nunca encontramos problemas con clientes obsoletos. Cuán estricto quiere ser un equipo dado aquí depende de su caso de uso específico, pero las PWA brindan una flexibilidad significativamente mayor que las aplicaciones nativas.
Erhalten Sie Cookie-Werte in einem Servicemitarbeiter
Manchmal ist es erforderlich, im Kontext eines Servicemitarbeiters auf Cookie-Werte zuzugreifen. In unserem Fall mussten wir auf die Cookie-Werte zugreifen, um ein Token zur Authentifizierung der ursprünglichen API-Anforderungen zu generieren. In einem Service Worker mögen synchrone APIs document.cookies
no están disponibles. Siempre puede enviar un mensaje a los clientes activos (con ventana) desde el trabajador del servicio para solicitar los valores de las cookies, aunque es posible que el trabajador del servicio se ejecute en segundo plano sin ningún cliente con ventana disponible, como durante una sincronización en segundo plano. Para solucionar esto, creamos un punto final en nuestro servidor Vorderes Ende que simplemente devolvía el valor de la Plätzchen al cliente. El trabajador del servicio realizó una solicitud de red a este punto final y leyó la respuesta para obtener los valores de las cookies.
Mit dem Start der
Cookie-Store-APIDiese Problemumgehung sollte für Browser, die sie unterstützen, nicht mehr erforderlich sein, da sie asynchronen Zugriff auf Browser-Cookies bietet und direkt vom Servicemitarbeiter verwendet werden kann.
Fallstricke für nicht generierte Servicemitarbeiter
Stellen Sie sicher, dass sich das Service Worker-Skript ändert, wenn Sie statische zwischengespeicherte Dateien ändern
Ein gängiges PWA-Muster besteht darin, dass ein Servicemitarbeiter alle statischen Anwendungsdateien während der Installation installiert
Installieren
Phase, in der Clients für alle nachfolgenden Besuche direkt auf den Caching-API-Cache zugreifen können. Service Worker werden nur installiert, wenn der Browser feststellt, dass sich das Service Worker-Skript auf irgendeine Weise geändert hat. Daher mussten wir sicherstellen, dass sich die Service Worker-Skriptdatei beim Ändern einer zwischengespeicherten Datei auf irgendeine Weise geändert hat. Wir haben dies manuell getan, indem wir einen Hash der statischen Ressourcendateien in unser Service Worker-Skript eingebettet haben, sodass jede Version eine andere Service Worker-JavaScript-Datei erstellt hat. Service-Worker-Bibliotheken wie
Arbeitsbox Automatisieren Sie diesen Prozess für Sie.
Unit Exam
Die Service Worker-APIs fügen dem globalen Objekt Ereignis-Listener hinzu. Zum Beispiel:
selbst.addEventListener('fetch', (evt) => evt.respondWith(holen('/foo')));
Esto puede ser difícil de probar porque necesita simular el disparador del Veranstaltung, el objeto del evento, esperar el Antworten mit ()
Rückruf, und warten Sie dann auf das Versprechen, bevor Sie das Ergebnis endgültig bestätigen. Eine einfachere Möglichkeit, dies zu strukturieren, besteht darin, die gesamte Implementierung an eine andere Datei zu delegieren, die einfacher zu testen ist.
importieren fetchHandler desde './fetch_handler.js';
selbst.addEventListener('fetch', (evt) => evt.respondWith(fetchHandler(evt)));
Aufgrund der Schwierigkeiten beim Unit-Test eines Service-Worker-Skripts haben wir das Kern-Service-Worker-Skript so einfach wie möglich gehalten und den größten Teil der Implementierung in andere Module unterteilt. Da es sich bei diesen Dateien nur um Standard-JS-Module handelte, konnten sie mit Standard-Testbibliotheken einfacher auf Einheitentests getestet werden.
Seien Sie gespannt auf Teil 2 und 3
In den Teilen 2 und 3 dieser Reihe werden wir uns mit Medienverwaltung und iOS-spezifischen Themen befassen. Wenn Sie uns mehr über das Erstellen einer PWA bei Google fragen möchten, besuchen Sie unsere Autorenprofile, um herauszufinden, wie Sie mit uns Kontakt aufnehmen können: