Le Web moderne est un miracle d’ingénierie, mais son histoire est parsemée de concepts brillants qui se sont concrétisés lors de leur exécution. Pour chaque innovation qui a échoué, il y a une technologie prometteuse qui est tombée à la renverse. Chacun de ces échecs offre une leçon de choses pour nous en tant que développeurs de logiciels.

Les nouvelles technologies sont en quelque sorte une contrainte. Nous aimons contempler les nouvelles charpentes brillantes à l’horizon, mais la véritable sagesse architecturale vient de l’examen de l’épave. Et depuis les migrations de versions catastrophiques et les rachats hostiles de HTML par des entreprises jusqu’à l’ignorance des réalités de la physique du Web et des limites physiques du front-end, nous avons de nombreuses ruines dont nous pouvons tirer des leçons.

Voici sept des échecs d’exécution les plus flagrants de l’histoire moderne du Web, ainsi que les leçons d’architecture que nous devons absorber pour garantir que nos bonnes idées ne subissent pas le même sort.

Web SQL : une impasse à fournisseur unique

La bonne idée : Intégrez une base de données relationnelle robuste directement dans le navigateur local. Activez des applications Web réactives et hors ligne. Synchronisez le tout avec un magasin de données back-end d’enregistrement.

Le défaut fatal : Politique de normes externes. Apple a poussé Web SQL, mais il s’agissait essentiellement d’un simple wrapper brut autour de SQLite. Google a intégré Web SQL dans Chrome, mais Mozilla et Microsoft ont hésité car le standardiser signifiait lier l’ensemble des spécifications Web à une bibliothèque C spécifique. C’était obsolète.

La leçon : Les normes nécessitent un consensus. Lier l’infrastructure Web à une seule implémentation est une recette pour une dépréciation soudaine. Bien que les développeurs aient perdu Web SQL et souffert du maladroit IndexedDB, le domaine a finalement progressé vers des domaines plus fertiles avec le PGLite basé sur Wasm et des solutions locales plus récentes comme PowerSync.

Angular 2 : Brûlez les navires

La bonne idée : Bâtissez sur le succès d’Angular avec une version améliorée et entièrement réécrite.

Lorsque Hernán Cortéz a incendié ses navires, cela s’est avéré être une stratégie brillante. Pour un framework Web grand public ? Pas tellement.

Angular.js était le roi incontesté des applications à page unique (SPA), mais il présentait des goulots d’étranglement en termes de performances. Cela ressemblait à un bidouillage de haut niveau. Google souhaitait introduire une architecture basée sur des composants qui la rendrait maintenable, conviviale et performante. Mais pour ce faire, ils ont dû d’abord le démolir jusqu’aux poteaux.

Le défaut fatal : Mauvaise stratégie de mise en œuvre. Google a annoncé une réécriture complète et non rétrocompatible qui a fondamentalement tout cassé. Il n’existait pas de voie de migration claire pour les bases de code d’entreprise massives.

Cela laissait la porte grande ouverte à un nouveau cadre. React a franchi cette porte et n’est jamais reparti.

La leçon : Ne rompez jamais le chemin de la migration. Même un chemin difficile respecte vos utilisateurs actuels, en leur disant que les développeurs apprécient leur participation continue.

Flow de Facebook : tomate de serre

La bonne idée : JavaScript avait besoin d’une sécurité de type pour satisfaire l’entreprise. Flow a introduit une inférence de type granulaire qui pourrait théoriquement protéger des bases de code massives avec un minimum d’annotations manuelles.

Malheureusement, le projet était une tomate de serre. Il a été conçu et développé dans l’environnement d’entreprise contrôlé de Facebook.

Le défaut fatal : Flow a été conçu pour l’environnement interne de Facebook. En dehors de Meta, Flow était notoirement bogué, nécessitait un serveur en arrière-plan lourd, tombait en panne sous Windows et ignorait l’écosystème open source plus large. Microsoft est intervenu adroitement dans la brèche avec TypeScript.

La leçon : Un écosystème ouvert et une expérience de développement transparente l’emporteront toujours sur les avantages tels que le premier arrivé et la supériorité technique brute. Même si vous êtes une méga-entreprise, gardez le projet lié à une utilisation active et large.

Google AMP : la flexibilité de l’entreprise

La bonne idée : À mesure que le mobile devenait massif, le Web avait du mal à offrir une expérience décente aux appareils portables. Les modes bien établis que nous avions cultivés au cours des 15 années précédentes étaient insuffisants, conduisant à des sites Web mobiles lents et maladroits, chargés de lourdes offres groupées et d’actifs non optimisés.

Google AMP (Accelerated Mobile Pages) était destiné à être une approche standard qui réduisait le HTML, le JavaScript et les images servies aux appareils mobiles et appliquait un cache CDN (réseau de diffusion de contenu) universel. Google avait le poids nécessaire pour accomplir tout cela.

Le défaut fatal : Google s’est appuyé sur la coercition pour faire réussir AMP. De plus, la technologie elle-même était trop rigide. Google a tenté de forcer les éditeurs à utiliser un sous-ensemble propriétaire et épuré de HTML en menaçant leur classement dans les recherches. C’était un cauchemar anti-concurrentiel et anti-innovation.

La leçon : Les standards du Web ouverts gagnent. Le verrouillage du fournisseur déguisé en « optimisation des performances » finira par être contourné et rejeté par la communauté.

Vous ne travaillez peut-être pas dans une puissance mondiale, mais des choses similaires se produisent même dans les petites et moyennes entreprises. Lorsque l’organisation tente d’imposer des normes rigides aux codeurs de base, cela peut produire des frictions, du ressentiment et de la rébellion. Les décrets descendants se déroulent rarement sans problème dans les logiciels.

Runtime CSS-in-JS : l’illusion de la performance

La bonne idée : CSS à grande échelle est notoirement difficile. Les collisions mondiales d’espaces de noms et les guerres de spécificité ont tourmenté les bases de code massives pendant des décennies. Colocaliser les styles directement dans les composants JavaScript a semblé être une révélation. Il a encapsulé la logique, éliminé le code mort et rendu les styles de gestion au sein des équipes d’entreprise distribuées incroyablement intuitifs.

Le défaut fatal : Nous avons ignoré la plateforme sous-jacente. En échange de cette belle expérience de développeur, nous avons accepté une implémentation d’exécution fondamentalement défectueuse. Nous avons passé cinq ans à forcer les navigateurs à télécharger d’énormes bundles JavaScript juste pour calculer et injecter des styles à la volée pendant le cycle de rendu. Nous avons pris quelque chose que le navigateur fait nativement à une vitesse fulgurante (analyser les feuilles de style) et avons forcé le moteur JavaScript monothread à le faire à la place, paralysant les temps de chargement initiaux et réduisant les performances du processeur mobile.

La leçon : N’échangez jamais les performances des utilisateurs contre l’expérience des développeurs. Lorsque les abstractions architecturales s’opposent aux capacités natives du navigateur, c’est toujours l’utilisateur final qui paie la taxe. Nous avons finalement dû ravaler notre fierté et nous rappeler que les navigateurs sont des machines à états hautement optimisées pour analyser le CSS natif. Cette dure leçon a ramené l’industrie aux modules CSS, aux fonctionnalités CSS natives modernes et aux compilateurs sans exécution comme Tailwind.

Micro-frontaux : bonne architecture, mauvais endroit

La bonne idée : Appliquez un découplage de type microservice au front-end, permettant aux grandes organisations d’accroître leur agilité en répartissant le développement de différentes fonctionnalités d’interface utilisateur entre différentes équipes.

Diviser l’interface utilisateur monolithique en composants distincts et plus petits qui pourraient être développés, testés et déployés indépendamment promettait les mêmes avantages que les microservices côté serveur : équipes autonomes, bases de code plus petites, maintenance plus facile, mises à jour incrémentielles. Nous pourrions tous travailler plus librement et aller plus vite. Mais qu’en est-il du pauvre utilisateur final ?

Le défaut fatal : Nous avons pris un modèle de back-end distribué et l’avons appliqué de force au navigateur. Cela n’avait pas vraiment de sens. Les micro-frontaux ont résolu un problème d’organisation, mais ont créé de la complexité, des frais généraux considérables et des problèmes de performances sur l’appareil de l’utilisateur final. Au lieu d’une application cohérente, les équipes ont fini par expédier plusieurs bundles JavaScript, des dépendances en double et parfois des versions entièrement concurrentes de frameworks d’interface utilisateur sur la même page. Le navigateur a été contraint d’agir comme un arbitre des systèmes distribués, conduisant à des états fragmentés, à une dégradation des performances et à une méta-complexité.

La leçon : La loi de Conway ne devrait pas dicter votre offre côté client. Ce n’est pas parce qu’une architecture distribuée résout les goulots d’étranglement de la mise à l’échelle du back-end qu’elle appartient au client. Vous ne devez jamais dégrader l’expérience de l’utilisateur final pour résoudre un problème au sein de l’organigramme de l’entreprise. Si vous flirtez avec une solution qui introduit de la complexité, faites appel au bon sens.

Au lieu de micro-frontaux, ce dont nous avions réellement besoin, c’était de modules ECMAScript et d’une infrastructure moderne sans construction.

SPA côté client uniquement : l’informatique distribuée frappe à nouveau

La bonne idée : Utilisez le navigateur comme plate-forme pour offrir une expérience de type client lourd et native. Gérez l’état localement, de manière réactive.

Le défaut fatal : Chaque fois que vous répliquez un état, vous introduisez les problèmes de l’informatique distribuée. C’est inévitable sur le Web. Le client a besoin que l’état soit utile à l’utilisateur. Dans les applications à page unique, comme on l’entend généralement, nous avons un moteur JavaScript qui exécute l’état de l’utilisateur et le synchronise avec le back-end via JSON.

Une couche architecturale entière est consacrée à la traduction des messages JSON entre les clients et le magasin de données. Une grande partie de la logique métier est concentrée chez le client. Le client est intelligent, le serveur est stupide.

La leçon : Le serveur existe pour une raison. L’industrie vient de passer les cinq dernières années à construire des méta-frameworks massifs juste pour revenir au rendu côté serveur à l’aide de Next.js et de frameworks full-stack similaires.

Contes édifiants

Ce n’est pas ce que vous voyez venir qui vous attrape. C’est la chose à laquelle tu n’as pas pensé. C’est souvent l’orgueil ou l’excès d’enthousiasme qui nous conduit dans les endroits sombres. Un savoir-faire technique avancé et une volonté d’agir peuvent être liés à des circonstances imparfaites. Seule la vigilance empêchera les projets logiciels de dérailler. Il faut continuellement vérifier comment se déroulent réellement les mises en œuvre, et non comment le plan le prévoit.

Si les poids lourds de la technologie figurant sur cette liste peuvent être dépassés par des résultats aussi malheureux, nous devons reconnaître que cela peut nous arriver. Cette reconnaissance est en soi la meilleure police d’assurance.

A lire également