Passer au contenu principal

Ce que l'équipe du Bulletin a appris sur les travailleurs de service lors du développement d'une PWA.

Ceci est le premier d'une série d'articles de blog sur les leçons que l'équipe Google Bulletin a tirées de la création d'une PWA externe. Dans ces articles, nous partagerons certains des défis auxquels nous sommes confrontés, les approches que nous adoptons pour les surmonter et des conseils généraux pour éviter de tricher. Il ne s'agit en aucun cas d'un aperçu complet des PWA. L'objectif est de partager les enseignements de l'expérience de notre équipe.

Pour ce premier article, nous aborderons d'abord un peu d'informations générales, puis nous plongerons dans tout ce que nous avons appris sur les travailleurs des services.

Le bulletin a été fermé en 2019 en raison d'un manque d'ajustement produit / marché. Nous avons encore beaucoup appris sur les PWA en cours de route!

igraal_fr-fr

Antécédents

Bulletin était en développement actif de mi-2017 à mi-2019.

Pourquoi nous avons choisi de construire une PWA

Avant de plonger dans le processus de développement, examinons pourquoi la création d'une PWA était une option intéressante pour ce projet:

  • Capacité à itérer rapidement. Particulièrement précieux car le Bulletin serait testé sur plusieurs marchés.
  • Base de code unique. Nos utilisateurs étaient à peu près également répartis entre Android et iOS. Une PWA signifiait que nous pouvions créer une seule application Web qui fonctionnerait sur les deux plates-formes. Cela a augmenté la vitesse et l'impact de l'équipe.
  • Mis à jour rapidement et quel que soit le comportement de l'utilisateur. Les PWA peuvent être automatiquement mis à jour, ce qui réduit le nombre de clients obsolètes dans la nature. Nous avons pu conduire des changements majeurs au backend avec un temps de migration très court pour les clients.
  • Il s'intègre facilement à vos propres applications et à des applications tierces. De telles intégrations étaient une exigence de l'application. Avec une PWA, cela signifiait souvent simplement ouvrir une URL.
  • Le frottement de l'installation d'une application a été supprimé.

Notre cadre

Pour Bulletin, nous utilisons Polymère, mais n'importe quel framework moderne et bien pris en charge fera l'affaire.

Ce que nous avons appris sur les travailleurs des services

Vous ne pouvez pas avoir une PWA sans une travailleur de service. Les techniciens de service vous offrent beaucoup de puissance, comme des stratégies de mise en cache avancées, des fonctionnalités hors ligne, la synchronisation en arrière-plan, etc. Bien que les travailleurs des services ajoutent une certaine complexité, nous avons constaté que leurs avantages l'emportent sur la complexité supplémentaire.

Générez-le si vous le pouvez

Évitez d'écrire un script de service worker à la main. L'écriture manuelle des services worker nécessite de gérer manuellement les ressources mises en cache et de réécrire la logique commune à la plupart des bibliothèques de service worker, telles que Boîte de travail.

Cela dit, en raison de notre pile technologique interne, nous n'avons pas pu utiliser une bibliothèque pour générer et gérer notre technicien de service. Nos apprentissages ci-dessous refléteront parfois cela. Accédez à Problèmes pour les techniciens de service non générés pour en savoir plus.

Toutes les bibliothèques ne sont pas compatibles avec les techniciens de service

Certaines bibliothèques JS émettent des hypothèses qui ne fonctionnent pas comme prévu lorsqu'elles sont exécutées par un service worker. Par exemple, en supposant la fenêtre ou document sont disponibles, ou en utilisant une API non disponible pour les techniciens de service (XMLHttpRequest, stockage local, etc.). Assurez-vous que les bibliothèques critiques dont vous avez besoin pour votre application sont prises en charge par les techniciens de maintenance. Pour cette PWA particulière, nous voulions utiliser
gapi.js pour l'authentification, mais ils n'ont pas pu le faire car il ne prenait pas en charge les techniciens de service. Les auteurs de bibliothèques doivent également réduire ou éliminer les hypothèses inutiles sur le contexte JavaScript dans la mesure du possible pour prendre en charge les cas d'utilisation des services worker, tels que la prévention des API de service worker incompatibles et le fait d'éviter l'état global.

Évitez d'accéder à IndexedDB pendant l'initialisation

Ne lis pas IndexedDB lors de l'initialisation de votre script de service worker, ou vous pouvez vous retrouver dans cette situation indésirable:

  1. L'utilisateur dispose d'une application Web avec IndexedDB (IDB) version N
  2. Une nouvelle application Web est incluse avec la version N + 1 de la BID
  3. L'utilisateur visite PWA, ce qui déclenche le téléchargement d'un nouveau service worker
  4. Le nouveau service worker lit dans la base de données IDB avant de s'enregistrer installer gestionnaire d'événements, activation d'un cycle de mise à jour BID pour passer de N à N + 1
  5. Étant donné que l'utilisateur dispose d'un ancien client avec la version N, le processus de mise à jour du service worker se bloque car les connexions actives sont toujours ouvertes à la version précédente de la base de données
  6. Le technicien de service se bloque et n'installe jamais

Dans notre cas, le cache est invalidé lors de l'installation du service worker, donc si le service worker n'a jamais été installé, les utilisateurs n'ont jamais reçu l'application mise à jour.

Rendez-le difficile

Bien que les scripts de service worker s'exécutent en arrière-plan, ils peuvent également être interrompus à tout moment, même lorsqu'ils sont au milieu d'opérations d'E / S (réseau, IDB, etc.). Tout processus de longue durée devrait pouvoir reprendre à tout moment.

Dans le cas d'un processus de synchronisation qui téléchargeait des fichiers volumineux sur le serveur et sauvegardés dans le BID, notre solution pour les téléchargements partiels interrompus consistait à tirer parti du système de reprise de notre bibliothèque de téléchargement interne, en enregistrant l'URL de téléchargement pouvant être reprise dans le BID avant le téléchargement. et utilisez cette URL pour reprendre un téléchargement s'il ne s'est pas terminé la première fois. De plus, avant toute opération d'E / S longue, l'état était sauvegardé dans l'IDB pour indiquer où nous en étions dans le processus pour chaque enregistrement.

Ne dépendez pas de l'état mondial

Étant donné que les techniciens de service existent dans un contexte différent, de nombreux symboles que vous pourriez espérer exister ne sont pas présents. Une grande partie de notre code fonctionnait sur les deux la fenêtre contexte, ainsi qu'un contexte de service worker (tel que l'enregistrement, les indicateurs, la synchronisation, etc.). Le code doit être défensif sur les services que vous utilisez, tels que le stockage local ou les cookies. Vous pouvez utiliser
globalThis

pour faire référence à l'objet global d'une manière qui fonctionne dans tous les contextes. Utilisez également les données stockées dans les variables globales avec parcimonie, car il n'y a aucune garantie lorsque le script se terminera et que l'état sera expulsé.

Développement local

La mise en cache des ressources localement est un élément important des agents de service. Cependant, pendant le développement, c'est le opposé que vous ne le souhaitez, surtout lorsque les mises à jour sont effectuées paresseusement. Vous souhaitez toujours installer le serveur de travail afin de pouvoir déboguer les problèmes avec celui-ci ou travailler avec d'autres API telles que la synchronisation en arrière-plan ou les notifications. Dans Chrome, vous pouvez y parvenir via Chrome DevTools en activant le Bypass pour le réseau case à cocherDemander panneau> Travailleurs de service panneau) en plus d'activer le Désactiver le cache case à cocher dans le Rapporter panneau pour désactiver également la mémoire cache. Pour couvrir plus de navigateurs, nous avons opté pour une solution différente en incluant un indicateur pour désactiver la mise en cache dans notre service worker, qui est activé par défaut dans les versions de développeur. Cela garantit que les développeurs obtiennent toujours leurs dernières modifications sans problèmes de mise en cache. Il est important d'inclure le Cache-Control: pas de cache en-tête également pour empêcher le navigateur de mettre en cache des actifs.

Phare

Phare fournit un certain nombre d'outils de débogage utiles pour les PWA. Il scanne un site et génère des rapports couvrant les PWA, les performances, l'accessibilité, le référencement et d'autres bonnes pratiques.
Nous recommandons exécution de Lighthouse en intégration continue pour vous faire savoir si vous ne répondez à aucun des critères pour être un PWA. Cela nous est arrivé une fois, alors que le technicien de service n'installait pas et que nous n'avions pas remarqué une augmentation de la production auparavant. Le fait d'avoir Lighthouse dans notre CI l'aurait empêché.

Adoptez la livraison continue

Étant donné que les techniciens de service peuvent se mettre à jour automatiquement, les utilisateurs n'ont pas la possibilité de limiter les mises à jour. Cela réduit considérablement le nombre de clients obsolètes dans la nature. Lorsque l'utilisateur a ouvert notre application, le technicien de service a servi l'ancien client tout en téléchargeant paresseusement le nouveau client. Une fois le nouveau client téléchargé, il demandera à l'utilisateur d'actualiser la page pour accéder aux nouvelles fonctionnalités. Même si l'utilisateur ignorait cette demande, la prochaine fois qu'il actualiserait la page, il recevrait la nouvelle version du client. En conséquence, il est assez difficile pour un utilisateur de rejeter les mises à jour de la même manière qu'il le peut pour les applications natives.

Nous avons pu conduire des changements majeurs au backend avec un temps de migration très court pour les clients. Nous donnons généralement aux utilisateurs un mois pour passer à des clients plus récents avant d'apporter des modifications majeures. Étant donné que l'application fonctionnerait alors qu'elle était obsolète, il était possible que des clients plus anciens existent dans la nature si l'utilisateur n'avait pas ouvert l'application pendant une longue période. Sur iOS, les techniciens de service sont
expulsé après quelques semaines
donc ce cas ne se produit pas. Pour Android, ce problème pourrait être atténué s'il n'est pas publié alors qu'il est obsolète ou si le contenu est expiré manuellement après quelques semaines. En pratique, nous ne rencontrons jamais de problèmes avec des clients obsolètes. La rigueur d'une équipe dépend de votre cas d'utilisation spécifique, mais les PWA offrent beaucoup plus de flexibilité que les applications natives.

Obtenir les valeurs de cookie dans un service worker

Parfois, il est nécessaire d'accéder aux valeurs des cookies dans le contexte d'un technicien de service. Dans notre cas, nous devions accéder aux valeurs des cookies pour générer un jeton afin d'authentifier les requêtes API d'origine. Dans un service worker, des API synchrones comme document.cookies Ne sont pas disponibles. Vous pouvez toujours envoyer un message aux clients actifs (fenêtrés) du technicien de service pour demander les paramètres de cookie, bien que le technicien de service puisse s'exécuter en arrière-plan sans aucun client fenêtré disponible, comme lors d'une synchronisation en arrière-plan. Pour résoudre ce problème, nous avons créé un point de terminaison sur notre serveur frontal qui a simplement renvoyé la valeur du cookie au client. Le technicien de service a fait une demande réseau à ce point de terminaison et a lu la réponse pour obtenir les valeurs de cookie.

Avec le lancement du
API du magasin de cookies, cette solution de contournement ne devrait plus être nécessaire pour les navigateurs qui la prennent en charge, car elle fournit un accès asynchrone aux cookies du navigateur et peut être utilisée directement par le technicien de service.

Pièges pour les travailleurs des services non générés

Assurez-vous que le script du service worker change si vous modifiez des fichiers statiques mis en cache

Un modèle PWA courant permet à un technicien de service d'installer tous les fichiers d'application statiques pendant leur
installer phase, qui permet aux clients d'accéder directement au cache de l'API de mise en cache pour toutes les visites suivantes. Les services worker ne sont installés que lorsque le navigateur détecte que le script de service worker a changé d'une manière ou d'une autre, nous avons donc dû nous assurer que le fichier de script de service worker a changé d'une manière ou d'une autre lors de la modification d'un fichier mis en cache. Nous l'avons fait manuellement en incorporant un hachage de l'ensemble des fichiers de ressources statiques dans notre script de service worker, de sorte que chaque version produisait un fichier JavaScript de service worker différent. Les bibliothèques de service worker telles que
Boîte de travail Automatisez ce processus pour vous.

Examen de l'unité

Les API de service worker fonctionnent en ajoutant des écouteurs d'événements à l'objet global. Par exemple:

soi . addEventListener ( 'fetch' , ( evt ) => evt . respondWith ( fetch ( '/ foo' ) ) ) ;

Cela peut être difficile à tester car vous devez simuler le déclencheur d'événement, l'objet d'événement, attendre le répondre avec () callback, puis attendez la promesse, avant d'affirmer enfin le résultat. Un moyen plus simple de structurer cela consiste à déléguer l'intégralité de l'implémentation à un autre fichier, ce qui est plus facile à tester.

import fetchHandler de './fetch_handler.js' ;
soi . addEventListener ( 'fetch' , ( evt ) => evt . respondWith ( fetchHandler ( evt ) ) ) ;

En raison des difficultés de test unitaire d'un script de service worker, nous avons gardé le script de service worker de base aussi basique que possible, en divisant la plupart de l'implémentation en d'autres modules. Étant donné que ces fichiers n'étaient que des modules JS standard, ils pourraient être plus facilement testés unitairement avec des bibliothèques de test standard.

Restez à l'écoute pour les parties 2 et 3

Dans les parties 2 et 3 de cette série, nous parlerons de la gestion des médias et des problèmes spécifiques à iOS. Si vous souhaitez nous demander plus d'informations sur la création d'une PWA sur Google, visitez nos profils d'auteurs pour savoir comment nous contacter:

Erreur: Attention: Contenu protégé.