01Une webapp, pas une appli de store
Une pizzeria, ce n'est pas un bureau. Le Wi-Fi passe mal derrière les murs du fournil, la box
redémarre, l'abonnement saute. Et personne n'a envie de publier une application sur l'App Store
pour un outil interne, ni de gérer des mises à jour au compte-goutte.
La solution s'appelle une PWA, pour Progressive Web App. C'est un site web tout ce qu'il y a de
plus classique, hébergé sur un serveur de fichiers statiques, mais que le navigateur sait
installer et faire tourner comme une vraie application.
Concrètement, sur l'iPad du pizzaiolo : ouvrir l'adresse une fois, Partager, « Sur l'écran
d'accueil ». L'app prend son icône, se lance en plein écran sans barre d'adresse ni onglets, et
se verrouille en portrait. Un petit fichier manifeste décrit tout ça au système : le nom, les
icônes, la couleur de fond, le mode d'affichage.
- Installation en deux gestes, sans store
- Plein écran, orientation verrouillée
- Mise à jour en publiant un fichier
02Le service worker, la pièce maîtresse
Un service worker est un script que le navigateur installe à part de la page, et qui vient se
placer entre l'application et le réseau. C'est lui qui décide ce qui part sur internet et ce qui
est servi depuis la machine.
Celui-ci met l'application en cache dès la première visite, puis la sert systématiquement depuis
ce cache. L'app s'ouvre instantanément et n'attend jamais le réseau. En arrière-plan, et sans
bloquer l'affichage, il va chercher une version fraîche pour le lancement suivant. Coupez le
Wi-Fi, débranchez la box, sortez la tablette du bâtiment : elle démarre pareil.
- Cache d'abord, réseau ensuite
- Ouverture instantanée
- Rafraîchissement en tâche de fond
03Rien à aller chercher sur un serveur
L'autre moitié du problème, c'est la donnée. Une app qui démarre hors-ligne mais qui doit
interroger une API pour savoir quoi afficher n'est pas plus avancée.
Ici, il n'y a pas de serveur applicatif du tout. Quelle place cuit, depuis quand, laquelle
refroidit : tout vit dans le navigateur de la tablette. Pas de compte, pas de synchronisation,
aucun appel réseau au démarrage, donc rien qui puisse échouer. C'est aussi ce qui la rend
instantanée : il n'y a aucun aller-retour à attendre.
Et pour que ça tienne dans le temps réel, l'app enregistre des horodatages, pas des comptes à
rebours. Chaque place retient l'instant où la pizza est entrée ou sortie, et l'affichage
recalcule les durées à partir de l'heure courante, quatre fois par seconde. Verrouiller la
tablette, basculer sur une autre app, recharger la page, la laisser en veille une heure : au
retour, les couleurs sont justes.
- État local, aucun serveur applicatif
- Horodatages plutôt que compteurs
- Veille et rechargement sans conséquence
04Les pièges du hors-ligne
C'est là que se joue la différence entre une PWA de démo et une qui tient en production. Quatre
cas qui cassent la plupart des implémentations, traités ici :
Le portail captif. Un hotspot ou une box qui intercepte la requête renvoie
souvent sa propre page d'accueil, avec un code HTTP 200 tout à fait valide. Un cache naïf
l'enregistre à la place de l'application, et l'app est morte jusqu'à ce qu'on vide le cache. Ici
une réponse n'est mise en cache que si son contenu porte la signature de l'app.
La mise à jour ratée. L'ancien cache n'est supprimé qu'une fois la nouvelle
version confirmée en cache. Une mise à jour interrompue en plein service ne peut pas laisser la
tablette avec un écran vide.
L'écran blanc. Une navigation reçoit toujours une vraie réponse : le cache si
possible, sinon le réseau avec un délai maximum, sinon une page de secours minimale avec un
bouton « Réessayer ». Jamais de page morte.
Le correctif qui n'arrive jamais. Le navigateur compare octet par octet le
script du service worker pour décider s'il installe une nouvelle version. S'il est servi depuis
le cache HTTP, un correctif publié n'atteint jamais les tablettes déjà installées. Une règle
serveur le sert donc toujours frais. Un bouton « Mise à jour » dans l'app permet en plus de
forcer la vérification, sans rien perdre du service en cours.
- Cache protégé contre les portails captifs
- Suppression de l'ancien cache différée
- Réponse garantie, jamais d'écran blanc
- Script du service worker jamais mis en cache
05Les détails qui comptent en cuisine
L'écran reste allumé. L'API Wake Lock empêche la tablette de se mettre en veille
tant que l'app est au premier plan. Personne n'a à la toucher avec les mains pleines de farine
pour rallumer l'écran.
Plusieurs postes, plusieurs profils. Un paramètre dans l'URL isole les données.
Deux pizzerias, ou un poste de test à côté du poste réel, sans se marcher dessus. Avec un
garde-fou : quand iOS relance l'app installée sans ce paramètre, le profil n'est restauré que
s'il n'y en a qu'un seul, jamais au risque de charger les données d'un autre.
Des cibles tactiles pour de vrai. Grandes pastilles rondes, boutons d'au moins
44 pixels de haut, contrastes forts, interface sombre. Ça se lit et ça se tape à un mètre, dans
une cuisine.
- Wake Lock : écran allumé pendant le service
- Profils isolés par URL
- Interface pensée pour un usage à distance
06Zéro dépendance
Un fichier HTML, un service worker, un manifeste, quatre icônes. Pas de framework, pas d'étape de
build, pas de node_modules à maintenir, pas de faille à patcher dans une dépendance dont
j'ignore l'existence. Déployer, c'est copier des fichiers.
Pour un outil de cette taille, c'est le bon calibre. Le projet n'a besoin de rien pour tourner
aujourd'hui, et il n'aura besoin de rien dans cinq ans non plus.
- 1 400 lignes de HTML, CSS et JS
- 180 lignes pour le service worker
- Aucune dépendance externe