- L’approche HTML-first a permis de faire fonctionner le formulaire de demande d’un service public sans JavaScript, afin que les utilisateurs puissent finaliser leur demande même avec des appareils, navigateurs ou réseaux médiocres
- L’ancienne application React a été retirée au bout de 3 jours à cause des plaintes clients ; les problèmes venaient d’un mélange de spinners de chargement, d’un état JavaScript global, de défauts d’accessibilité et d’un système de stockage d’images limité par les 5 Mo de
localStorage - La nouvelle implémentation, basée sur Astro, a transformé chaque étape du formulaire en page distincte et a enregistré à chaque étape les données soumises et les fichiers téléversés dans une session backend, évitant ainsi la perte de données saisies
- La validation du formulaire a été gérée par un web component encapsulant la validation HTML native du navigateur, avec une structure d’amélioration progressive qui basculait en cas d’échec vers la validation par défaut du navigateur puis vers la validation de l’API backend
- Après le lancement, le nombre d’utilisateurs ayant terminé le formulaire a doublé, révélant aussi que les utilisateurs abandonnant à cause d’un échec JavaScript n’apparaissent pas dans les outils d’analyse fondés sur JavaScript
Contexte du problème et tentative précédente ratée
- Le client était une entreprise de services publics, et la souscription au service pouvait se faire via un ancien formulaire ASP sur le site ou par une procédure manuelle
- La procédure manuelle coûtait plus cher à l’entreprise, dans un contexte de monopole régulé où une satisfaction client tombant sous 96 % pouvait entraîner des amendes de plusieurs millions de livres
- Deux tentatives précédentes pour résoudre le problème avaient échoué, et lors de la plus récente, des prestataires d’un autre pays avaient développé une application React
- L’application React a été retirée 3 jours après sa mise en ligne à cause des plaintes clients
- Cette application mêlait spinners de chargement et état JavaScript global, sans offrir une accessibilité correcte
- Le téléversement d’images était une fonction essentielle du formulaire, mais l’application essayait de stocker les images et toutes les données du formulaire dans
localStorage, limité à 5 Mo
Les critères retenus en faveur du HTML-first
- Le nouveau site a été construit avec Astro et a adopté une architecture HTML-first
- JavaScript n’était utilisé qu’à l’intérieur de web components, avec pour rôle d’améliorer progressivement un site qui fonctionne correctement même sans JavaScript
- Le principe retenu était qu’un service public doit fonctionner sur tous les appareils possibles
- Le principe retenu était aussi qu’il doit fonctionner même avec une mauvaise connexion
- Une fois saisies, les données d’un formulaire ne doivent jamais disparaître
- L’exemple de Terence Eden montre que les pages HTML simples de GOV.UK permettaient de consulter des informations sur les aides au logement même dans le navigateur de la PlayStation Portable, lent et souvent à court de mémoire
- Les pages de GOV.UK étaient écrites en HTML simple et léger, conçu pour fonctionner même dans des navigateurs catastrophiques
Structure du formulaire et conservation des données
- Chaque session du formulaire devait avoir un identifiant unique
- À chaque étape de l’assistant, les données soumises et les fichiers téléversés devaient être enregistrés côté backend
- Il fallait pouvoir terminer le formulaire sans JavaScript
- Il fallait pouvoir terminer le formulaire même avec des navigateurs web anciens et peu performants
- L’accessibilité devait respecter les critères WCAG, et l’équipe visait le niveau AA plutôt que AAA
- JavaScript et le CSS moderne devaient servir à améliorer l’expérience
- Dans l’architecture finale, chaque étape de l’assistant de formulaire est devenue une page distincte, et lorsque l’utilisateur cliquait sur Suivant, le formulaire était soumis
- Si l’API considérait les données comme valides, le navigateur était redirigé vers l’étape suivante
- La soumission de formulaire suivie d’une redirection est un ancien pattern des applications web, qui a connu un petit retour en grâce moderne grâce à Remix
- Ce service n’était pas une application affichant des données en temps réel, mais un gros formulaire ; envoyer 20 Mo de JavaScript avant même le rendu n’était donc pas approprié
Validation du formulaire et amélioration progressive
- La validation de formulaire et l’affichage des erreurs sont souvent traités comme un domaine où les équipes dépensent de nombreux mois-personnes à cause des bibliothèques de validation React
- Les navigateurs intègrent déjà un système de validation, exploitable avec moins d’effort qu’une imitation de moindre qualité nécessitant la gestion d’une bibliothèque séparée
- Le web component HTML mis en œuvre était un simple élément personnalisé encapsulant le HTML existant
- Ce web component n’utilisait pas le shadow DOM et ne rendait quasiment pas de HTML dans le JavaScript
- Le composant encapsulait le formulaire HTML et récupérait la validation HTML pour l’afficher sous une forme moderne
- Les infobulles popup de validation HTML étaient bloquées et les erreurs placées dans un élément
aria-describedbyassocié au champ - Aujourd’hui, l’usage de
aria-errormessageest recommandé - Lorsqu’un champ redevenait valide pendant la saisie, la validation était effacée, puis réévaluée au
bluret au moment de la soumission - Cette expérience utilisateur tenait en moins de 1 Ko et, en cas d’échec, revenait à la validation native du navigateur
- Si la validation native du navigateur échouait aussi, l’API backend prenait en charge la validation
- Les problèmes de validation étaient signalés au plus tôt possible selon ce que le navigateur de l’utilisateur permettait, avec en permanence un fallback vers une expérience acceptable en cas d’échec
- Une nouvelle version du web component a ensuite été entièrement réécrite pour un usage général, sous le nom validation-enhancer
- L’exemple d’utilisation montre que
validation-enhancerencapsule un formulaire HTML et réutilise directementinput type="email",requiredetaria-errormessage
Email
Submit
Résultats du lancement et conclusion
- Après le lancement, le nombre de personnes ayant terminé le formulaire a doublé
- Les analystes ne savaient pas d’où venaient ces utilisateurs
- Les outils d’analyse basés sur JavaScript ne voient pas les utilisateurs qui abandonnent à cause d’un échec JavaScript
- L’approche consistant à conserver une session backend et à ne jamais perdre les données utilisateur a porté ses fruits
- Dans un cas, un utilisateur a terminé le formulaire un mois après l’avoir commencé
- Une fois la mission terminée, le successeur a estimé qu’une architecture fonctionnant toujours sans JavaScript créait davantage de travail pour l’équipe
- Exclure les utilisateurs de vieux navigateurs, les utilisateurs avec une mauvaise connexion réseau ou ceux qui utilisent des technologies d’assistance est inacceptable pour un service public en situation de monopole
- Il faut cesser de pousser des méthodes brutales et immatures issues de la phase d’expansion de l’industrie du logiciel
- Si l’on construit une application web qui fonctionne sur une PlayStation Portable avec une connexion 3G, elle fonctionnera pour tous les utilisateurs, et pourra encore fonctionner dans 30 ans
2 commentaires
Avis sur Hacker News
En tant que développeur non web, je me demande pourquoi cette approche demanderait plus de travail
L’approche décrite dans l’article a l’air assez simple : il suffit de créer des composants standard pour les formulaires et de mettre un bouton d’envoi en dessous. C’est ce que je faisais déjà il y a longtemps quand je créais des sites personnels, et ce n’était pas si difficile. C’est peut-être parce que je ne connais pas bien ce domaine, mais créer un frontend sophistiqué me paraît bien plus compliqué
Ce n’est pas parce qu’ils sont stupides. Si on leur demande directement « Peut-on créer un site sans React ? », ils répondront évidemment « oui ». Mais si on leur demande de créer un nouveau site, par habitude et par envie d’en finir, ils lancent un nouveau projet React sans trop réfléchir
Certains ne connaissent réellement pas d’autre méthode. Ils ne savent pas monter un simple serveur HTTP qui envoie du HTML pur, ni créer des formulaires validés et soumis sans JavaScript. Ce ne sont pas les gens qui écrivent sur HN, ni ceux qui participent aux discussions en ligne sur de nouveaux outils ou technologies, ou sur d’anciens outils et technologies. Ils ont appris juste ce qu’il fallait pour être embauchés via un bootcamp ou un seul cours universitaire de webapp, puis ont appris au fil de l’eau uniquement les outils spécifiques exigés par leur employeur ou choisis par quelqu’un dans leur équipe
En prenant de l’âge, il m’a fallu du temps pour m’en rendre compte, mais maintenant je comprends. Selon leur parcours, certaines personnes découvrent les aspects les plus simples de HTML, CSS et JavaScript pur après les parties complexes et spécifiques aux frameworks de ces mêmes technologies. Du coup, cela leur semble non pas moins professionnel, mais au contraire plus obscur, plus avancé, ou plus annexe
Dire « ça nous donne beaucoup plus de travail » n’est donc pas forcément faux de façon intentionnelle. Quand on travaille avec des outils peu familiers, cela peut réellement donner l’impression de demander bien plus de travail, même s’ils sont moins complexes
L’application était rapide et simple, mais il y avait un prix à payer. Ma capacité à réutiliser directement des éléments d’interface riches via des paquets npm était limitée, et fournir une bonne expérience utilisateur demandait bien plus de travail. Tout prenait plus de temps et, au final, l’expérience utilisateur était aussi moins bonne. J’y ai prêté attention, mais il arrive qu’on n’ait pas le temps de tout soigner jusqu’au bout
L’entreprise a échoué, et je ne pense pas que React l’aurait sauvée. Mais je peux dire d’expérience qu’une obsession morale pour la « simplicité » n’aide pas non plus. Il y a toujours des trade-offs
Quelqu’un dit avoir proposé une solution plus simple et plus raisonnable que celle à laquelle la plupart auraient pensé, et la personne qui a repris le projet n’était pas satisfaite
Sait-on si la qualité du code transmis était bonne ? Cette personne a-t-elle réagi au simple fait que « ce n’était pas du React » ? Y avait-il dans l’entreprise un modèle imposé pour la manière de construire les applications ?
Impossible à savoir
Je n’en entends plus beaucoup parler depuis un moment, mais la proposition HTML Triptych fait toujours partie de celles que j’aimerais voir un jour intégrées aux navigateurs. La manière dont les formulaires HTML dialoguent avec des endpoints REST est un bon modèle
La validation d’assistance côté utilisateur se fait via les attributs d’entrée, la vraie validation se fait de l’autre côté de la requête, et le flux devient GET /form => POST /thing => GET /thing/1. Si la fonctionnalité triptych est implémentée, ce sera un excellent modèle
[0] https://triptychproject.org/
Je n’aime pas du tout les sites React, mais ce que je ne comprends pas, c’est : est-ce que ces sites ne font vraiment aucun chargement différé ?
Même une grosse application monopage peut être très rapide si elle ne charge les composants qu’au moment où ils sont nécessaires
Je suis passé de Angular1 à Vue2 puis à Svelte2, avant de me fixer sur des composants web purs sans shadow DOM, et c’est agréable et rapide à utiliser
De nos jours, je construis la plupart des apps simplement avec HTMX + Go + SQLite
J’ai trouvé que c’était suffisant pour la plupart des projets
L’un de mes sites contient beaucoup d’images et traite 10 To de trafic par mois. Dans ce cas, la configuration est la suivante : 1. j’utilise S3 parce qu’il me faut un stockage de données fiable 2. je mets Cloudflare devant et j’active le Tiered Cache. Ainsi, les POP préfèrent récupérer depuis Cloudflare plutôt que depuis l’origine. Je mets tout en cache pendant un an à la fois côté navigateur et côté Cloudflare, et j’ai défini des règles qui ignorent la politique de cache d’origine et les paramètres de requête, en n’utilisant que des objets immuables nécessitant un versioning 3. je mets BunnyCDN devant tout ça
Cloudflare seul ne permet pas vraiment d’exploiter un site riche en images, donc cette méthode réduit fortement les coûts. Selon leur politique, il ne faut pas l’utiliser principalement pour les images, mais pour le HTML, le CSS, le JavaScript et les autres contenus du site
Si on n’utilise que S3, le coût devient énorme
En revanche, ces derniers temps je développe une app mobile. Les PWA ont des limites. Le système d’exploitation peut récupérer le stockage IndexedDB, donc on ne peut pas fournir un stockage de données fiable dans l’app sans inscription ni intervention du backend
Au final, j’ai dû passer à Flutter sur Android, mais cela a apporté une autre forme de douleur. C’est frustrant quand une mise à jour de l’app reste longtemps en « examen ». En comparaison, la web app de la même app se met à jour très vite
Je me demande pourquoi il n’existe pas de système d’exploitation mobile qui permette de créer des apps en JavaScript, HTML et CSS tout en fournissant un stockage stable sans gros effort. La rapidité de mise à jour des apps PWA est un vrai avantage
Le voyage temporel est la partie facile ; ensuite, il faut somehow empêcher la chute de Palm et éviter que webOS ne soit oublié comme système d’exploitation pour smartphone
Si 2009 est trop loin, on peut aussi tenter sa chance avec Firefox OS en 2012
Blague à part, des gens et des entreprises ont déjà essayé. Mais à cause d’un mauvais timing et d’une série d’événements, cette réalité n’a pas pu se produire dans notre ligne temporelle
J’ai l’impression qu’il se situe exactement au point optimal : sans la charge inutile du C, tout en se mettant de côté comme Java pour permettre de se concentrer sur la logique métier. Ce n’est pas comme Rust
Ce n’est pas bon pour tout. Son manque de capacité à créer des abstractions est particulièrement regrettable. Mais pour les applications serveur avec beaucoup de logique métier, c’est formidable. On a l’impression d’un langage spécialisé dans ce domaine, pas d’un langage qui veut tout faire
J’ai aussi créé quelques bibliothèques pour abstraire les parties SQL et HTMX/web/OAuth. Mes apps se ressemblent maintenant beaucoup, donc il est facile de réutiliser des fonctionnalités
https://github.com/cattlecloud/webtools
https://github.com/cattlecloud/litesql
En contrepoint, il y a In Defence of the Single Page Application
https://williamkennedy.ninja/javascript/2022/05/03/in-defenc...
In Defence of the Single Page Application - https://news.ycombinator.com/item?id=31275178 - mai 2022, 32 commentaires
Cet article est bon, et c’est un excellent exemple d’un problème concret résolu avec la bonne technologie et le bon niveau de profondeur. Avoir une connaissance complète du domaine métier du client aide énormément
En revanche, je n’aime pas le cadrage du type « le HTML simple est meilleur que React ». On pourrait raconter exactement la même histoire en étant développeur React
Je pourrais aussi parler sans fin de nombreux sujets survolés ici, comme la complexité et les subtilités du stockage de session côté serveur par rapport au stockage côté navigateur, mais ce serait trop long
Les choses simples en HTML restent simples dans React
C’est littéralement le même code. Rien n’empêche d’utiliser dans React la validation HTML native du navigateur. Le code qui devient complexe dans React, par exemple une logique de validation excessivement compliquée, devient aussi complexe dans Astro. Astro a aussi sa propre manière de gérer la validation par schéma, etc., et pour l’intégrer à un site Astro il faut aussi intégrer un routeur client, entre autres, donc il est très facile d’y tomber également dans une complexité excessive
Le point de comparaison est sans doute aussi une équipe d’externalisation étrangère avec une connaissance imparfaite, et la structure du projet les incite à produire une solution le plus vite possible, en y passant le moins de temps possible, avec autant de complexité que nécessaire
Ce dernier point est subtil. Cela ne veut pas dire que le prestataire le fait intentionnellement, mais la structure des incitations fait qu’une complexité excessive leur profite réellement, donc ils n’ont pas d’incitation directe à aller vers une solution simple
Quoi qu’il en soit, une solution simple qui traite directement le problème du moment est toujours meilleure, quel que soit le stack choisi
Je n’ai rien contre la validation de formulaires dans Astro ; je voulais simplement souligner qu’il y a davantage à dire que la seule « validation HTML native du navigateur »
Excellent texte, mais chaque fois que je lis ce genre de texte inspirant, je suis toujours partagé. L’idée d’un site simple est séduisante : quelque chose de totalement juste, qui fonctionne bien, se charge vite et ne dépend pas des navigateurs les plus récents.
Puis je me demande si ce n’est pas simplement parce que je ne suis pas assez intelligent pour comprendre React ou la techno à la mode du moment.
J’ai l’impression qu’il existe une limite de compréhension que je ne pourrai jamais franchir. Donnez-moi un éditeur simple comme Sublime et demandez-moi de créer une page web, et même avec du JavaScript, c’est un environnement dans lequel je suis heureux. Donnez-moi VSCode ou Zed, des plugins Claude/Copilot/ChatGPT collés partout, et des tutoriels React, et j’ai le cerveau qui se liquéfie.
Garder les choses simples n’a rien de mauvais ; souvent, il faut au contraire être assez intelligent pour ne pas les rendre inutilement complexes.
Embrace Extend Extinguish est bien réel, et ceux qui y adhèrent méritent d’être remplacés par des LLM qui mentent plus vite et recrachent du code poubelle.
Ça me rappelle il y a presque 15 ans. On utilisait la gestion de session côté back-end avec Grails, et des formulaires HTML améliorés avec du CSS responsive et “un peu” de JS.
La différence avec aujourd’hui, c’est que les technologies des navigateurs n’étaient pas aussi avancées. Il fallait gérer plusieurs navigateurs, jusqu’à IE7, voire IE6, ce qui était difficile et exigeait une QA très étendue. BrowserStack n’est arrivé que plus tard.
Il y a une raison pour laquelle les bibliothèques JavaScript ont évolué. npm n’existait pas, et même bower n’existait pas encore. Puis Backbone.js est arrivé, et je l’aimais bien. AngularJS était incroyable, ensuite la version suivante d’Angular a introduit une grosse rupture de compatibilité, puis React, Polymer, etc. sont arrivés.
Les navigateurs natifs d’aujourd’hui peuvent faire énormément de choses et il est facile d’ajouter progressivement des fonctionnalités. Mais ça n’a pas toujours été le cas. À l’époque, la décision d’utiliser React était justifiée pour plusieurs raisons, et ça a très bien pu être le cas ici aussi.
J’ai construit ce type d’applications sur GOV.UK pour le ministère de la Justice il y a plus de 10 ans. Nous avions créé notre propre bibliothèque d’assistant de formulaires, capable de valider de longs formulaires étape par étape et de les répartir sur plusieurs pages, parce que Ruby on Rails ne le faisait pas nativement.
À l’époque, le principe selon lequel tout le monde devait pouvoir utiliser les services numériques, quel que soit l’environnement depuis lequel il y accédait, était extrêmement important.
Pour chaque ID de session, on peut faire correspondre les pages d’une application multipage avec cet ID de session, de sorte que l’utilisateur puisse même le saisir lui-même si nécessaire. Mais avec suffisamment d’informations — comme l’adresse IP, la date du téléversement, le navigateur ou le système d’exploitation — on devrait pouvoir l’identifier. Cela dit, la session la plus précise doit se trouver dans le navigateur, afin que le cookie d’une demande unique ne soit pas mélangé avec celui d’un autre demandeur, comme un parent qui utiliserait une PlayStation Portable.
Je me demande quelles technologies ils utilisent pour les applications mobiles. J’imagine qu’il ne s’agit pas d’apps mobiles complètes, mais plutôt de webviews.
Ce n’est pas « on a remplacé une app React par des formulaires HTML, et les performances se sont améliorées ». C’est « on a remplacé une mauvaise page web par une bonne page web, et les performances se sont améliorées ».
Il est idiot d’attribuer ça à la technologie qui alimente l’expérience dans le navigateur. On peut créer une excellente expérience utilisateur avec React, et on peut aussi faire un site affreux en HTML pur.
L’amélioration vient d’un changement de conception, pas d’un changement de technologie.
Mais oui, c’est vrai. Les changements côté utilisateur viennent de la correction de la conception, pas de la technologie utilisée.
Ça ressemble beaucoup à une mauvaise puce sur un CV. Quelqu’un affirme par exemple « réécrit le site web en HTML-first, augmentation de 100 % du nombre de visiteurs », comme si le résultat business venait du changement de code. Mais si on interroge cette ligne, on finit par admettre qu’il y a eu une refonte complète du site pour corriger des problèmes de design ou ajouter des fonctionnalités, et que c’est cela qui a entraîné la hausse du trafic.
JavaScript: The Good Parts de Douglas Crockford est ridiculement court. React: The Good Parts serait encore plus court.
Fait amusant, le texte d’origine décrit un formulaire de type assistant multipage, un style qu’on ne voyait quasiment plus depuis une dizaine d’années. Pourtant, chaque fois que j’en ai vu un, c’était en général dans un système d’entreprise épouvantable. Le dernier que j’ai vu était quelque chose comme un produit Oracle pour gérer des notes de frais.
Le problème de ces systèmes, c’est toujours leur lenteur en cours de tâche. On doit attendre plusieurs secondes à chaque bouton. Et si on doit revenir d’une ou deux étapes, c’est deux fois plus agaçant. Les applications monopage mal conçues ont tendance à être lentes au démarrage : le chargement prend du temps, mais une fois chargées, les performances sont généralement correctes.
Avis sur Lobste.rs
Construire quelque chose qui fonctionne vraiment correctement pour les gens demande évidemment plus de travail. Mais c’est aussi, au fond, le cœur même du travail
Ce que voulaient sans doute vraiment dire les prédécesseurs, c’est qu’ils ne maîtrisent pas très bien les fondamentaux de la plateforme web
Ça ne veut pas dire que c’est souhaitable, juste que c’est la réalité actuelle
Le passage où il explique qu’il a fallu du temps pour présenter à ses collègues le principe de « soumission de formulaire et redirection » est assez amer. C’est parce que tout le monde s’est habitué aux applications web centrées sur le client
Le développement web est vraiment dans un état triste aujourd’hui, et il y a beaucoup de choses à réenseigner
Je ne pense pas qu’il faille un niveau de compatibilité aussi élevé pour justifier cette approche. Comme le dit l’article, au fond, ce n’est qu’un formulaire
Donc, à sa place, je construirais ça ainsi dans tous les cas
J’aimerais travailler à construire des sites comme celui décrit dans l’article. La contrainte d’un téléchargement minuscule qui doit fonctionner sur presque tous les navigateurs tout en restant accessible ressemble à un défi vraiment intéressant
Je me demande s’il existe des entreprises spécialisées là-dedans, et si elles recrutent. Peut-être que je suis juste une personne plus âgée nostalgique de l’ancienne simplicité
La fonctionnalité est suffisamment bien isolée pour qu’il soit très facile d’en extraire une bibliothèque réutilisable, et il reste encore beaucoup à faire. Ça donne envie d’intégrer ce genre de chose dans les valeurs par défaut des frameworks web. Vraiment un très bon article
Ironiquement, sur Firefox, à cause d’un certain style, le corps de l’article n’était ni complètement visible ni sélectionnable, donc j’ai dû passer en mode lecture. Je voyais le titre, les guillemets roses et les blocs de code, mais pas le reste
Édit : en voyant les commentaires ci-dessous, c’est probablement un problème de mon environnement. Je laisse ça pour le contexte
J’ai quand même bien lu l’article. Que l’on soit développeur ou utilisateur final, nous payons tous le prix de « l’agilité » de React. Je me suis souvent dit au travail que j’aimerais pouvoir utiliser une autre stack
J’ai aussi été impressionné par l’empathie de l’auteur et par la manière dont il l’a transformée en une conception où « tout le monde y gagne ». Le fait de se soucier des autres finit par payer
Je m’y reconnais beaucoup. J’ai autrefois créé un blog extrêmement chargé en JavaScript, et les fonctionnalités basées sur JS ont presque provoqué une révolte
Je n’ai pas encore eu le temps de le migrer vers une approche HTML-first, mais en apparence je l’ai au moins fait ressembler à une page web HTML-first
Dans mes données d’analyse, j’ai observé des résultats similaires. Le taux de rebond est passé d’environ 80 % à environ 50 %, et sur les articles suivants, le nombre de nouveaux visiteurs a presque doublé
Quand je pense au nombre de personnes qui éviteront peut-être mon domaine pour toujours à cause de la catastrophe que j’avais d’abord implémentée en JS, ça fait froid dans le dos. Pour une page web ou un blog, c’est l’un des conseils les plus importants
Cette manière de faire aide aussi pour le remplissage automatique des formulaires. J’ai déjà vu des formulaires entièrement dynamiques, sans attributs permettant d’identifier chaque partie, ce qui rendait l’autoremplissage impossible
C’était dommage de voir quelque chose surconçu pour être joli plutôt que fonctionnel, donc j’ai pris plaisir à lire cet article sur une conception qui met l’utilisateur en premier
En y ajoutant du streaming SSE et une bibliothèque de morphing, on peut aussi construire de manière assez élégante des fonctionnalités dynamiques, temps réel et multijoueur