Vers une convergence des frameworks JavaScript
Lors de la dotJS Conference, des acteurs clés de l’écosystème JavaScript ont appelé à une forme de standardisation des fonctionnalités clés des frameworks JS, à commencer par l’implémentation des signaux dans le langage, un mécanisme de réactivité de plus en plus répandu.
Réunion. Voilà le maître mot des organisateurs de la dotJS Conference 2024 ayant eu lieu à Paris le 27 juin. La précédente édition de l’événement s’était tenue en 2019, il y a cinq ans. Depuis, la fragmentation de l’écosystème JavaScript s’est accentuée.
Non seulement les frameworks côté client pullulent, mais il y a également quantité de méthodes pour arriver aux mêmes résultats avec ce langage très utilisé par les développeurs. Un vrai labyrinthe pour les néophytes et un motif de surcoût pour les entreprises qui développent des applications Web.
Certains sites référencent plus d’une centaine de frameworks JavaScript. Le rapport State of JS 2023 témoigne de phénomènes d’adoption hétéroclites, même si React, Vue.js et Angular apparaissent comme les outils les plus utilisés et les plus appréciés.
Si c’est un sujet d’agacement (et donc une formidable corne d’abondance à memes), ce foisonnement de méthodes et d’outils est aussi le reflet d’un « écosystème vibrant », comme l’indique Christophe Porteneuve, présentateur lors de la dotJS Conference et Senior Staff Engineer chez Doctolib.
Pour autant, JavaScript est un langage standardisé par l’ECMA International sous le nom ECMAScript (standard ECMA-262). De fait, plusieurs efforts sont en cours pour uniformiser le fonctionnement des fondations de plusieurs frameworks front-end.
L’un d’eux s’articule autour des signaux. Ici, il s’agit en particulier de gérer les états (des valeurs statiques) et la réactivité d’une application Web.
Problèmes de réactivité, multiplication des frameworks : deux enjeux de taille pour l’écosystème
Dans le contexte de JavaScript, « un signal représente un état réactif – une valeur qui peut changer dans le temps et informer automatiquement les calculs et effets dépendants de ces changements », explique dans un billet de blog Rakesh Purohit, développeur React chez DhiWise, un éditeur d’un framework de développement permettant de convertir des designs de type Figma en du code exploitable par des développeurs.
Pour Rakesh Purohit, « c’est la pierre angulaire de la programmation événementielle, qui permet un style de codage plus déclaratif où le flux de données, plutôt qu’une série d’étapes impératives, dicte la logique ».
Concrètement, à quoi servent les signaux dans l’écosystème JavaScript ? « À beaucoup de choses », répond Ben Lesh, leader du projet RxJS, ingénieur logiciel principal chez Bridgewater Associates (ex-Google et Netflix), lors de son intervention aux Folies Bergères.
« Tout d’abord, cela permet de retarder le calcul de tâches coûteuses jusqu’à ce qu’elles soient réellement nécessaires. Si vous mettez à jour quelque chose très rapidement de manière asynchrone, vous pouvez différer le calcul pour optimiser les performances. De plus, cette approche avancée permet de définir des dépendances claires entre les calculs et les signaux », poursuit-il.
« Par exemple, un calcul peut dépendre des signaux a et b, tandis qu’un effet peut dépendre des signaux c, qui eux-mêmes dépendent de a et b. Cela crée une chaîne de dépendances gérée de manière efficace et réactive ».
Cette chaîne de dépendances est formellement représentée par un graphe qui associe des valeurs et des logiques pour la notification, l’invalidation, le calcul et la « memoization » ou « memoïsation » (l’optimisation des opérations par leur mise en cache).
Minko GechevResponsable du produit et des relations avec les développeurs pour Angular, Google
« Les signaux permettent de suivre les changements de données spécifiques dans une interface utilisateur », résume de son côté Minko Gechev, responsable du produit et des relations avec les développeurs pour Angular chez Google. Par exemple, sur un site e-commerce, si un utilisateur change la quantité d’un article dans son panier, seuls les composants affichant cette quantité seront mis à jour, sans vérifier tous les composants de la page. « Cela rend les mises à jour de l’UI plus efficaces et rapides », considère-t-il. Plus l’application Web est complexe, plus ce mécanisme semble important.
Le concept n’est pas spécifique à l’écosystème JavaScript. Un système similaire existe dans la librairie front-end QT, établie sur C++.
De même, dans l’écosystème JavaScript, les signaux « existent depuis très longtemps », dixit Ben Lesh, une dizaine d’années environ. « Ils sont également connus sous le nom de propriétés calculées dans Emberjs, ce sont les observables dans Knockoutjs, dans MobX, les signaux dans Angular et Solidjs, les runes Spelt, les refs Vuejs », liste-t-il.
Les différences entre les signaux et les observables
Il ne faut pas confondre ces différentes implémentations du concept de signaux avec les observables dans RxJS. Cette librairie a été conçue pour gérer des événements asynchrones et couvre d’autres cas d’usage que les signaux. Les observables dans RxJS « représentent des événements, traités comme des collections de n valeurs » et sont stateless, indique Ben Lesh. À l’inverse, les signaux sont généralement stateful et ne gèrent qu’une valeur à la fois, qui évolue à travers le temps.
Du fait de leur versatilité, les observables sont plus complexes à exploiter et sont plus souvent utilisés pour l’annulation de tâches et la coordination d’événements.
Une proposition pour les concepteurs de frameworks
Dévoilée le 1er avril 2024 (mais en travaux depuis environ un an), la proposition TC39 concernant les signaux vise à « définir la sémantique de base précise du graphe de signaux ». L’API proposée dans cet appel à la standardisation est dédiée aux frameworks dont les concepteurs peuvent s’inspirer « pour assurer l’interopérabilité, grâce à un graphe de signaux commun et un mécanisme de suivi automatique ».
Les contributeurs principaux des projets Angular, Bubble, Ember, FAST, MobX, Preact, Qwik, RxJS, Solid, Starbeam, Svelter, Vue ou encore Wiz, participent à cet effort de standardisation depuis environ un an.
De fait, les mécanismes de suivi automatique des modifications des valeurs et des logiques qui affectent l’interface utilisateur sont souvent différents selon les frameworks JavaScript.
« Il est donc difficile de partager des modèles, des composants et des bibliothèques entre différents frameworks, qui ont tendance à être faussement couplés à leur moteur de visualisation (étant donné que les signaux sont généralement mis en œuvre dans le cadre des frameworks JS) », notent les auteurs de la proposition.
Et de suggérer une liste de prérequis pour rendre la gestion des signaux la plus uniforme possible.
Il existe ainsi deux types de signaux. Le signal de base représente une valeur. Le signal calculé peut être le résultat de l’application d’une formule sur deux signaux ou plus. Les deux sont généralement « wrappés » par les frameworks associés.
L’implémentation proposée doit avoir peu d’impact sur les performances. Ainsi, les signaux calculés sont mis en cache et sont recalculés uniquement si une dépendance de graphe de signaux a changé. Des comparaisons personnalisées aident à déterminer quand les signaux calculés doivent être mis à jour.
Du fait des dépendances, le changement d’état d’un signal de base peut entraîner la modification des signaux calculés qui en dépendent. Des mécanismes de réactions identifient les changements et programment le recalcul des signaux calculés. Les effets (les opérations résultant du changement de données) sont exécutés selon le plan de travail déterminé par les réactions.
Si possible, les signaux de base et calculés pourront être gérés par le collecteur de déchets « comme n’importe quelle valeur JavaScript ».
Bien que ce projet soit encore à la deuxième étape sur cinq (Stage 1) d’intégration dans le langage, Google est déjà en train de l’implémenter dans AngularJS et Wiz. Wiz est peu connu, car il s’agit d’un framework propriétaire utilisé en interne par le géant du cloud.
Quand AngularJS est utilisé pour développer Google Analytics, les interfaces des services de GCP, Wiz est généralement manipulé par les équipes derrière Gmail, YouTube et Workspace.
« AngularJS est souvent utilisé pour des interfaces hautement interactives quand Wiz est plutôt associé aux applications grand public où la latence est très importante », justifie Minko Gechev. « Mais les équipes associées aux différents produits commençaient à vouloir des fonctionnalités provenant des deux frameworks. L’on m’a assigné, avec d’autres, ce projet de convergence ».
Ainsi, les équipes derrière AngularJS et Wiz ont fait en sorte que les signaux Angular puissent être exploités avec Wiz.
Une implémentation déjà en production chez YouTube
« À l’heure actuelle, l’ensemble du trafic mobile de YouTube utilise Wiz avec les signaux Angular », annonce Minko Gechev. « L’équipe a constaté des améliorations significatives de la performance. Par exemple, sur les Smart TV, la latence des entrées [quand un utilisateur appuie sur un bouton de sa télécommande N.D.L.R.] a été améliorée de 35 %. Le défilement de Shorts YouTube est passé à 60 images par seconde, contre 25 images par seconde en général avec le virtual DOM ».
Ainsi, l’ingénieur considère que l’uniformisation de la gestion des signaux dans le langage JavaScript est en bonne voie.
Minko GechevResponsable du produit et des relations avec les développeurs pour Angular, Google
« L’implémentation de référence utilise les signaux Angular parce qu’elle a prouvé qu’elle pouvait fonctionner avec plusieurs frameworks et qu’elle s’adaptait à YouTube, le deuxième plus grand site Web au monde », avance-t-il. « De plus, faire converger différents frameworks est quelque chose dont je n’avais jamais eu vent par le passé. En fait, les concepteurs de frameworks ont souvent essayé de prendre des directions différentes, même si certaines idées reviennent et semblent être des bonnes pratiques ».
Cette convergence n’est pas seulement interne. Progressivement, Google prévoit de combiner les fonctionnalités d’Angular et de Wiz dans la branche open source d’Angular. Minko Gechev anticipe que cela prendra plusieurs années.
Finalement, le responsable des relations développeur chez Google considère que les frameworks JS deviennent des « méta freamworks ». Selon un slide qu’il a partagé, Angular, Next.js, Remix, Nuxt, SolidStart et SvelteKit partagent des fonctionnalités communes. Les outils s’appuient sur des composants, fournissent un DOM virtuel ou incrémental, ils prennent en charge la génération statique de site, le rendu côté serveur, le langage TypeScript, ou encore des fonctions réactives de base et avancées (comme les signaux).
D’autres fonctionnalités devraient faire l’objet d’une forme de rapprochement. Minko Gechev parie sur l’adoption d’approches identiques, sinon similaires concernant la structure des vues, l’injection de dépendances, la relecture des événements et l’actualisation sélective des composants d’une UI (une fonction que l’on pourrait traduire par l’expression « irrigation partielle »).
« Comment choisir un framework de nos jours ? Ne réfléchissez pas trop », conseille-t-il. « Il s’agira toujours de la même technologie avec une casquette différente ».
Reste que l’implémentation d’éléments des signaux pourrait encore faire l’objet d’interprétations différentes suivant les concepteurs, notent certains développeurs. D’autres considèrent cela comme une « erreur ».
Minko Gechev note, lui, que les enjeux de stabilité et de fiabilité sont parfois mis de côté par les équipes de développement. « Nous voulons nous assurer que nous utilisons une solution stable qui nous accompagnera sur le long terme. Il est également très important de disposer d’un écosystème riche, inclusif et solidaire, et d’une solution que l’on aime vraiment utiliser », conclut-il.