- La plateforme web manque aujourd’hui d’une API de templates déclarative dont les développeurs ont réellement besoin
- Dans la plupart des frameworks web modernes, le templating est une technologie centrale, mais l’API DOM standard ne propose pas de moyen sûr et efficace de créer et mettre à jour des templates
- Cela entraîne des frictions et des pertes de performances pour les utilisateurs, les développeurs, les frameworks et même la plateforme elle-même
- Le moment est venu d’introduire une API de templates : l’expérience accumulée dans les frameworks récents et les fonctionnalités de JavaScript rendent désormais sa mise en œuvre et sa standardisation plus réalistes
- En combinant plusieurs modèles, comme l’identité de template et la réactivité basée sur les signaux, l’article esquisse l’orientation possible d’une API de templates de nouvelle génération
Résumé de la proposition
- Cet article explique le contexte et la nécessité d’ajouter une API de templates déclarative à la plateforme web
- L’API DOM est puissante, mais le DOM standard ne dispose pas d’une API de templates permettant de créer et mettre à jour plusieurs nœuds de manière sûre et efficace à partir de données
- React, Vue, Angular et les autres frameworks majeurs font tous du templating déclaratif un élément central, car il apporte de nombreux avantages en matière de productivité, de sécurité, de performances, d’analyse statique et de rendu côté serveur
- En l’absence d’une API de templates, les utilisateurs, les développeurs, les frameworks et la plateforme subissent tous une complexité inutile, des risques de sécurité, des baisses de performances et des barrières à l’entrée
- L’auteur soutient que le moment est opportun pour introduire cette API et propose une standardisation progressive en s’appuyant sur l’expérience des frameworks existants et les fonctionnalités modernes de JavaScript
Pourquoi les templates sont nécessaires, et les problèmes actuels
- L’API DOM constitue la base des capacités dynamiques de la plateforme web
- Mais le DOM standard ne fournit pas de moyen déclaratif pour définir en toute sécurité un arbre DOM à partir de données et le mettre à jour efficacement
- Tous les frameworks web modernes (React, Vue, Angular, Svelte, etc.) proposent un templating déclaratif
- Les raisons de la popularité du templating déclaratif sont les suivantes
- une meilleure ergonomie et une meilleure lisibilité que les API impératives
- une meilleure sécurité XSS grâce à l’échappement automatique des données dans les templates
- des performances de rendu efficaces et rapides
- des gains de productivité via l’analyse statique, le typage, l’IntelliSense, etc.
- la prise en charge du rendu côté serveur
Les problèmes de la situation actuelle
- Utilisateurs : chargement initial plus lent à cause du téléchargement des bibliothèques et du délai de rendu. La taille accrue du code client dégrade l’UX
- Développeurs : nécessité d’utiliser des bibliothèques séparées (npm, CDN, etc.) pour profiter des templates. Barrières à l’entrée et chargement non standard
- Frameworks : obligation d’implémenter eux-mêmes leur moteur de templates. Forts compromis entre performances, fonctionnalités et taille du code
- Plateforme : désavantage concurrentiel face aux applications natives. Flutter, SwiftUI et d’autres proposent un système de templates intégré
Pourquoi c’est le bon moment
- Les tentatives passées autour des templates (E4X, E4H, les template literals HTML, etc.) ont échoué, mais elles souffraient alors de faiblesses sur la mise à jour du DOM
- Les frameworks récents et la communauté ont désormais accumulé suffisamment de bonnes pratiques autour des API de templates
- Une proposition d’API basée sur JavaScript est possible. Le JS standard dispose déjà aujourd’hui des tagged template literals
- La demande pour une manipulation plus pratique du DOM continue d’augmenter chez les développeurs vanilla JS et dans la communauté des Web Components
- Des propositions de primitives de bas niveau comme DOM Parts progressent en parallèle, mais une API déclarative de haut niveau peut offrir une utilité plus grande et une direction d’évolution plus claire
Analyse d’exemples de bonne syntaxe de templates
- Les systèmes de templates dominants (React-JSX, Vue, Svelte, Angular, etc.) reposent, au fond, sur une syntaxe très similaire de type balisage + liaisons
- Dans le cas des templates fondés sur une API JS, l’expression de template renvoie généralement une description du DOM, puis une fonction de rendu séparée l’applique au DOM réel
- Les anciennes tentatives comme E4X renvoyaient directement le DOM lui-même, ce qui donnait un modèle de mise à jour moins satisfaisant
Possibilités d’une API de templates basée sur JavaScript
- Grâce aux tagged template literals, il est possible de concevoir une API de templates sans introduire de nouvelles fonctionnalités JavaScript
- Il existe déjà plusieurs démonstrations concrètes, comme JSX-to-Lit
Discussion sur l’intégration de JSX
- La standardisation de JSX nécessite une définition sémantique complexe ainsi qu’une sémantique d’exécution. JSX n’est en soi qu’une syntaxe
- Le JSX non standard actuel n’est qu’une transformation syntaxique ; si une API de templates standard est adoptée à l’avenir, il pourra être relié à un compilateur de transformation JSX -> template literals
- Si une véritable standardisation de JSX arrive plus tard, il sera alors plus facile d’évoluer vers une structure acceptant les types de données adaptés à l’API de templates
Relation avec une API de templates basée sur HTML
- De nombreux développeurs et communautés demandent un système de templates HTML
- Cependant, un système fondé sur HTML représente un chantier bien plus vaste, car il nécessite de concevoir une nouvelle syntaxe et de nouvelles expressions pour les liaisons, le langage d’expression, les structures de contrôle, etc.
- La raison pour laquelle des frameworks récents (comme Lit) sont passés de templates HTML à une API JS est la même
- Ainsi, une API de templates basée sur JS pourrait être introduite en priorité, avec une extension progressive vers une API HTML par la suite
Maturité de l’expérience en matière de réactivité
- Plusieurs modèles de réactivité ont fait leurs preuves : VDOM diffing (React), identité de template (Lit), signaux (fine-grained signals, Solid/Svelte/Vue, etc.)
- Les approches fondées sur le VDOM sont plus lentes, tandis que la combinaison identité de template + modèle à signaux est rapide, efficace et plus explicite
- L’approche basée sur les signaux suppose que toutes les données soient enveloppées dans des signaux, mais elle peut aussi coexister avec des données ordinaires
Trajectoire d’évolution et effets attendus
- L’API de templates JS déclarative proposée apporterait des bénéfices directs au vanilla JS, aux Web Components et aux nouveaux frameworks
- Elle pourrait aussi servir aux frameworks existants comme cible de compilation, backend d’exécution, ou API directement prise en charge
- Elle prendrait en charge à la fois l’approche de type « rerendering » et la réactivité basée sur les signaux
- Elle préparerait aussi le terrain pour une extension future vers des templates déclaratifs basés sur HTML et des custom elements déclaratifs
- Le périmètre de l’API est réduit et clair, et son intégration avec des API existantes (comme DOM Parts) est également facilitée
- En revanche, même si l’API et la syntaxe paraissent simples en surface, la surface d’implémentation sous-jacente — DOM Parts, scheduler, etc. — est large, et nécessite une collaboration sur la standardisation et les tests
Conclusion
- L’auteur discute actuellement de cette proposition dans une issue GitHub et appelle à la participation de la communauté, notamment des ingénieurs plateforme
1 commentaires
Avis Hacker News
Ce qui me fait sourire quand on dit « nous savons ce qu’est une bonne syntaxe de template », c’est qu’en réalité il n’y a jamais vraiment eu de consensus solide, même sur ce critère. À mon avis, dans le templating, l’expérience visuelle compte plus que la perspective symbolique. C’est aussi pour cela que des outils comme Dreamweaver ont eu autant de succès à l’époque. C’est dans la même logique que beaucoup de designers commencent leur apprentissage avec des outils comme Photoshop. Je trouve dommage que cette tentative ressemble à une recréation de XSLT. Le vrai problème du templating, c’est de faire converger une structure mal conçue vers un résultat bien conçu. Il y a aussi le problème de représenter des entités liées, comme
labeletfor, qui sont connectées sans appartenir au même arbre. Si je pouvais faire de la magie, j’aimerais qu’on arrête d’essayer à tout prix de faire rentrer de force chaque élément dans une mise en page documentaire standard bizarre. Avec un bon usage du positionnement absolu, on peut résoudre efficacement beaucoup de problèmes d’UI ; je me demande donc pourquoi on cherche encore et encore à forcer la machine à prendre en charge jusqu’aux calculs mathématiquesJe suis d’accord sur le fait que cela ressemble à une tentative de recréer XSLT. Je n’aimais pas vraiment XML en soi, mais XSLT était vraiment puissant. C’est d’ailleurs une fonctionnalité encore largement prise en charge dans les navigateurs. XML montrait clairement ses limites pour la configuration ou l’IPC, mais l’association d’un excellent langage de balisage et de la puissance de transformation de XSLT est, selon moi, quelque chose qui n’a jamais été pleinement exploité. Si XSLT ne s’est pas popularisé, c’est parce que c’était un véritable DSL déclaratif et fonctionnel. Beaucoup de gens parlent positivement des DSL, mais en pratique ils se contentent souvent d’un mince habillage autour de la sémantique procédurale d’un langage populaire. Avec un DSL bien conçu, on peut traiter simplement des tâches complexes, et je pense que l’effort d’apprentissage a fait défaut
Tu dis que la visualité est au cœur d’une vraie syntaxe de template, mais j’aimerais comprendre comment tu en arrives à cette conclusion. De mon point de vue, cela ressemble plutôt à une critique de HTML+CSS eux-mêmes, autrement dit du mode de génération. Je me demande aussi pourquoi tu évoques le positionnement absolu. Il est certes utile dans certains cas, mais lorsqu’on l’utilise pour la mise en page globale, cela devient au contraire difficile à maintenir et casse facilement selon la taille de l’écran ou la quantité de contenu. Même une mise en page de journal comporte en réalité beaucoup de subtilités liées au texte et à la typographie, qu’on ne peut pas résoudre avec le seul positionnement absolu. Quand on travaille CSS en profondeur, j’ai souvent constaté qu’il était au final plus rapide et plus simple de reconstruire une mise en page initialement pensée en positionnement absolu avec flex ou flow.
calc()et les unités de viewport peuvent avoir du sens, mais en pratique, sauf pour un contenu ou un viewport complètement fixes, le positionnement absolu n’est pas adaptéJ’ai déjà vu l’argument selon lequel les gens contournent les choses de manière inutilement compliquée pour obtenir au final le même effet que ce qu’un bon usage du positionnement absolu permettrait de faire simplement et rapidement. Mais sur le Web, il faut qu’un document soit bien présenté sur tous les appareils, quelles que soient leur taille, leur orientation ou leurs performances. Les applications classiques, comme les applications Windows, n’ont pas ce problème, et les applications mobiles n’ont souvent qu’à prendre en compte des tailles d’écran standardisées. Seul le Web doit réellement gérer tout cela
Réagir avec ironie à l’expression « bonne syntaxe de template » ne me paraît pas très respectueux envers ceux qui défendent une forme de progrès. Et je pense qu’il existe aujourd’hui de bonnes syntaxes de template, JSX en étant l’exemple principal. Je ne suis pas fan de React, mais je pense que JSX a révolutionné le développement web, et que la plupart des systèmes de template JS ont presque tous convergé vers une structure de type « template comme expression », « composition par imbrication » et contrôle de flux géré en JavaScript
React et Svelte ne se ressemblent qu’en surface ; dans leur fonctionnement réel, ils sont assez différents. Le cœur de React, c’est qu’une fonction JavaScript (presque) ordinaire renvoie du balisage paresseux sous forme de JSX. Il n’y a pas de syntaxe de template propre aux boucles ou au rendu conditionnel ; tout est géré en JavaScript classique, et c’est une différence majeure
J’apprends sans cesse que les API et les ABI (interfaces binaires d’application) ne sont jamais vraiment définitives. Les besoins des applications ne sont pas figés ; ils changent au fil du temps, donc il n’existe pas d’API parfaite qui puisse servir éternellement. Cette proposition en est un bon exemple. D’abord, le problème est résolu dans des bibliothèques utilisateur comme React, puis il finit par descendre dans le standard. Les polyfills suivent le même schéma. Même si ce genre de proposition réussit, elle finit tôt ou tard par devenir une ancienne technologie, puis de nouvelles approches émergent pour la contourner. DOM API, ECMA, anciens navigateurs : tous suivent le même destin. Cela amène à se demander si l’entropie technique, l’extensibilité et la rétrocompatibilité elles-mêmes ne devraient pas être considérées comme des cas d’usage standards
Chaque nouvelle fonctionnalité ajoutée aux standards du Web finit par créer une énorme charge de maintenance côté code, et augmente aussi la quantité de code que doivent implémenter les navigateurs conformes au standard. Des projets comme Servo se retrouvent sans cesse à devoir poursuivre l’expansion de la plateforme juste pour essayer de rattraper leur retard. J’aimerais que la plateforme web puisse disposer de toutes les capacités d’un environnement natif, dans les limites de la vie privée et du sandboxing. Je veux aussi une excellente expérience développeur. Mais pour réaliser ce rêve, il faut se demander quel prix on est prêt à payer en complexité. Je ne suis pas convaincu que le templating natif discuté ici améliore réellement l’expérience développeur de façon nette
Si l’on maintient la rétrocompatibilité sans modifier l’interface, est-ce que le versioning ne joue pas justement ce rôle ?
L’idée qu’avec le temps tout finit par être contourné ou patché est vraie, mais il y a aussi un effet positif : la fonctionnalité de base monte d’un cran à chaque étape. Les mises à jour progressives gardent toute leur valeur, même si les besoins des utilisateurs continuent de révéler de nouveaux manques et de nouveaux cas d’usage
Je ne suis pas d’accord avec l’affirmation selon laquelle « les API et les ABI ne sont jamais stables pour toujours ». Par exemple,
getElementByIdest restée stable depuis plus de 25 ans. Dire qu’une API immuable est impossible ressemble davantage à une forme de résignation personnelle, alors qu’il existe d’innombrables contre-exemples. La demande est sans fin ; il suffit donc d’ajouter de nouvelles API. Inutile de casser celles qui fonctionnent déjàSur le Web, dès qu’une API est publiée, quelqu’un finira par dépendre exactement de cette forme pour le restant de sa vie. C’est pourquoi les répercussions de décisions prises il y a 20 ans se font encore sentir aujourd’hui. On le voit par exemple dans des cas comme « smooshgate »
En évoquant la mode de la programmation réactive, certains affirment que le niveau userland a suffisamment expérimenté dans ce domaine, et qu’il serait désormais possible de créer un vrai système standard en ne gardant que les avantages des différentes approches. Mais des projets comme Ryan Carniato/Solid JS explorent encore de nouvelles possibilités autour des signals, donc j’ai le sentiment que l’exploration n’est pas terminée. Il reste largement de quoi progresser
Le Web a vraiment besoin de templates natifs, de réactivité et de data binding. Le gaspillage de CPU et de bande passante causé par les milliards d’utilisateurs dans le monde qui téléchargent, parsèment et exécutent des frameworks lourds comme React est difficile à imaginer
Comparé au gaspillage massif de ressources provoqué par les LLM et les opérations cryptographiques, ce gaspillage-là paraît presque négligeable
Une proposal autour des signals est en cours au TC39, ce qui permet d’avancer d’un pas supplémentaire
En pratique, tout ce qu’il faut pour le développement, c’est essentiellement du data binding bidirectionnel et une sorte de clone de JSX
React n’est pas un système de template
En suivant les discussions sur l’introduction d’un système de template haut niveau dans les standards du Web, j’en viens plutôt à penser que la priorité devrait être de fournir des API bas niveau intégrées au navigateur. Il est presque impossible que tout le monde s’accorde sur un système de template standard. En revanche, il suffirait que le navigateur fournisse une API bas niveau pour appliquer un diff au DOM. On pourrait imaginer nativement une méthode comme :
element.applyDiff(DocumentFragment | string, { method: 'innerHTML' | 'outerHTML' }). L’application d’un diff permettrait de mettre à jour l’élément courant de manière non destructive, en préservant le focus, la valeur des inputs, l’état de l’audio/vidéo, etc. Il existe des bibliothèques JS comme Idiomorph, mais une solution native aurait de fortes chances d’être bien plus rapideL’auteur de ce texte est présenté comme l’un des experts les plus expérimentés du domaine. Il a largement contribué à Lit, Polymer, aux web components de Google et à plusieurs spécifications fondamentales du DOM
Au lieu de l’approche JSX, j’aimerais une approche syntaxique du type de ce que Kotlin a généralisé avec les receivers et les builders pour les DSL. Ce genre de mécanisme peut être très utile bien au-delà de simples templates HTML, pour des hiérarchies de composants variées, de la configuration et bien d’autres contextes. En fin de compte, le vrai sens du templating et du data binding n’est qu’un ensemble standard de fonctions exploitant ce type de capacités syntaxiques, un peu à la manière de Jetpack Compose
Je ne suis pas toujours convaincu que le templating déclaratif soit supérieur à jQuery. J’utilise React depuis presque 10 ans, mais plus ma SPA devient complexe, plus le contrôle impératif du DOM me manque. L’abstraction du DOM fuit, et au final un simple schéma de type « last-write-wins » paraît parfois plus clair. On dit que les templates déclaratifs résolvent ce genre de problème, mais dès qu’on commence à partager un état mutable entre composants, les limites apparaissent très vite
Cette impression vient aussi du fait que, côté développeurs React, appeler directement les API du DOM est parfois traité comme un péché. Pourtant, utiliser activement des refs ou retrouver et manipuler directement des composants par
idest tout à fait acceptable. D’ailleurs, certaines bibliothèques de formulaires rapides, avec peu de rerenders, fonctionnent précisément comme celaJe n’aime pas spécialement React, mais je pense qu’il n’y a pas de véritable barrière à sortir du DOM déclaratif pour utiliser
innerHTML, des refs, etc. Le contrôle impératif reste possible, et dans la pratique il y a peu de choses qu’on ne puisse pas faire en déclaratif.attachShadow()oushowModal()peuvent eux aussi être facilement enveloppés de façon déclarative avec une dizaine de lignes en plusSi la proposal Records and Tuples avait progressé, JSX aurait pu exploiter cette structure pour acquérir une nouvelle sémantique. En réalité, cette proposal n’a pas simplement stagné : elle a été entièrement retirée (voir l’issue). Elle a été remplacée par la proposal composites
Je pense qu’il faut arrêter ces discussions sur la standardisation de fonctionnalités haut niveau. Il vaut mieux étendre les caractéristiques de plus bas niveau et se concentrer sur ce qui apporte davantage de valeur à l’implémentation des bibliothèques de niveau supérieur. Si une proposition standard n’offre pas d’avantage clair par rapport à une bibliothèque, elle n’a pas vraiment de sens. À mon avis, il ne faudrait entamer une discussion de standardisation qu’après au moins 5 à 10 ans de validation large dans l’écosystème des bibliothèques