2 points par GN⁺ 2023-11-14 | 1 commentaires | Partager sur WhatsApp
  • Les composants web peuvent sembler être la version navigateur des composants React, mais en réalité ils se rapprochent davantage d’un modèle qui place le HTML existant au centre et y ajoute des fonctionnalités
  • La différence clé réside dans le rendu avant l’exécution de JavaScript : plutôt que de passer des données à un élément personnalisé vide, il est plus naturel d’envelopper du HTML porteur de sens dans un élément personnalisé
  • Un HTML web component étend le balisage existant, tandis qu’un élément vide dont le contenu et les fonctionnalités reposent entièrement sur JavaScript se rapproche davantage d’un composant web JavaScript
  • Si l’approche de composition façon React est familière avec l’idée de remplacement, les composants web demandent une logique d’augmentation : ajouter des fonctionnalités tout en conservant le contenu
  • Sur la plateforme web, comme avec HTML5, fetch ou certaines évolutions liées à TypeScript, les bonnes idées ont tendance à survivre longtemps en renforçant les technologies existantes plutôt qu’en les évincant

Les composants web et les composants React n’ont pas la même logique

  • Le nom « web components » peut donner l’impression qu’il s’agit de l’équivalent, sur la plateforme web, des composants React
    • Le JSX de React utilise la forme <MyComponent>, tandis que les composants web peuvent utiliser la forme <my-component>
    • Mais si l’on crée des composants web comme on crée des composants React, on risque vite d’être frustré
  • Les deux technologies diffèrent par les capacités qu’elles privilégient et leur mode d’utilisation
    • Vouloir utiliser l’une comme l’autre va à l’encontre de la direction naturelle de chaque technologie

Les composants web HTML sont mieux adaptés à l’augmentation qu’au remplacement

  • Un composant React classique peut prendre la forme d’un composant vide auquel on passe des données via des propriétés, JavaScript se chargeant de rendre l’ensemble du contenu
<UserAvatar
  src="https://example.com/path/to/img.jpg";
  alt="..."
/>
  • À première vue, un composant web peut être écrit de la même manière
<user-avatar
  src="https://example.com/path/to/img.jpg";
  alt="..."
></user-avatar>
  • Mais la force propre des composants web est qu’ils permettent un rendu avant JavaScript
    • Les composants React ne peuvent pas fonctionner de cette manière
  • C’est pourquoi, plutôt qu’un « composant coquille » vide, il est souvent plus pertinent de construire le contenu principal en HTML puis de l’envelopper dans un élément personnalisé qui y ajoute des fonctionnalités
<user-avatar>
  <img src="https://example.com/path/to/img.jpg"; alt="..." />
</user-avatar>
  • La distinction proposée par Jeremy dans « HTML web components » se concentre sur le fait qu’un élément personnalisé étende ou non un balisage existant
    • Si l’élément personnalisé est vide, ce n’est pas un composant web HTML
    • S’il enveloppe un balisage existant pour l’étendre, il se rapproche d’un composant web HTML
  • Un « JavaScript web component » désigne une forme où le contenu et les fonctionnalités d’un élément vide dépendent entièrement de JavaScript
<user-avatar
  src="https://example.com/path/to/img.jpg";
  alt="..."
></user-avatar>
  • Sous cette forme, sans JavaScript, cela n’a aucun sens pour l’utilisateur final
  • À l’inverse, un composant web HTML conserve du sens et du contenu même sans JavaScript, et lorsque JavaScript est présent, il vient y ajouter des fonctionnalités
<user-avatar>
  <img src="https://example.com/path/to/img.jpg"; alt="..." />
</user-avatar>

Sur le web, l’approche par augmentation dure dans le temps

  • Si l’approche augmentative fonctionne bien sur le web, c’est parce que la nature du web encourage un renforcement progressif résilient et qu’elle convient bien à la transformation répétée d’un ensemble aussi vaste que le web
  • Les bonnes idées issues des frameworks et bibliothèques autour du web, même lorsqu’elles sont absorbées par la plateforme, y entrent souvent sous une forme qui renforce l’existant au lieu de le remplacer entièrement
    • XHTML a tenté de remplacer HTML4, tandis que HTML5 a cherché à renforcer HTML4, et c’est HTML5 qui l’a emporté
    • Des bibliothèques de réseau ont essayé de remplacer XMLHttpRequest, et leurs bonnes idées ont fini par être intégrées dans le standard fetch
    • fetch existe aujourd’hui aussi dans de nombreux environnements hors navigateur
    • Les bonnes idées de Sass et de jQuery ont également été reprises par les navigateurs
    • Les bonnes idées de TypeScript arrivent elles aussi dans les navigateurs en renforçant les technologies existantes plutôt qu’en les remplaçant
  • On peut voir les composants web comme une évolution où le modèle de composant de React arrive dans le navigateur, mais davantage sous une forme qui renforce le fonctionnement déjà en place du web qu’une forme qui le remplace
  • Si l’on recherche une approche technique durable, mieux vaut choisir l’augmentation et l’amélioration plutôt que le remplacement, car c’est plus conforme à la direction prise par le web

1 commentaires

 
GN⁺ 2023-11-14
Avis de Hacker News
  • J’espérais que cet article expliquerait ce que user-avatar fait ou fournit réellement, mais ce n’est jamais venu
    S’il ne contient que du style, je ne vois pas pourquoi on n’utiliserait pas simplement une classe CSS, et il semblerait bien plus naturel que user-avatar accepte un attribut src plutôt que d’obliger à y mettre une balise img à chaque fois
    Vue/React/Angular ne cherchent pas tant à « remplacer » HTML qu’à s’empiler au-dessus de HTML/CSS/JS ; si tout était rendu dans un canvas, cet argument m’aurait paru plus convaincant
    J’avais de l’espoir pour les Web Components lorsqu’ils ont été annoncés, mais leurs fonctionnalités fournies par défaut sont trop limitées, et ils donnent peu l’impression d’aider concrètement à créer des applications web comme le font les frameworks
    Les alternatives aux gros frameworks, en particulier des choses comme htmlx, ressemblent à une variante de jQuery avec un peu de sucre syntaxique, ce qui semble être un net retour en arrière pour construire des applications web

    • Je suis d’accord pour dire que « les alternatives aux gros frameworks ressemblent à du sucre syntaxique autour de jQuery », mais je ne vois pas bien pourquoi ce serait un choix complètement erroné pour construire des applications web
      Si par « application web » on entend quelque chose comme Google Sheets, je suis d’accord, mais ce courant anti-React semble plutôt critiquer l’habitude de partir d’un framework par défaut et de tout construire dessus dès le départ
      Il existe beaucoup de sites web qui n’ont en réalité besoin que d’« une légère couche d’interaction » par-dessus
    • Je pense que l’article d’Eric Meyer illustre beaucoup mieux l’intention : https://meyerweb.com/eric/thoughts/2023/11/01/blinded-by-the...
      Le principal avantage est l’amélioration progressive : comme une balise img a un comportement par défaut, on peut s’appuyer sur le rendu de base et ne « renforcer » avec des composants web que les parties nécessaires
    • Faute d’exemples concrets, cet article donne un peu l’impression d’une idée venue sous la douche
    • Un exemple qui montre plus concrètement l’idée de l’article est plutôt celui-ci : https://www.zachleat.com/web/details-utils
      Le composant details-utils renforce le comportement du composant HTML intégré detail
      Si JavaScript est désactivé pour une raison quelconque, le composant detail fonctionne toujours comme prévu ; si JavaScript est activé ou une fois le téléchargement terminé, il bénéficie de comportements améliorés, comme se replier lors d’un clic à l’extérieur
      Dans cette approche, la partie réutilisable est précisément ce renforcement du comportement
      C’est en voyant ce composant web du créateur de 11ty que j’ai compris le propos de l’article, et le point qui m’avait frappé en découvrant les Web Components — « au final, il faut quand même JavaScript, et sans lui ça ne marche pas » — apparaît aussi dans l’article de Rich Harris : https://dev.to/richharris/why-i-don-t-use-web-components-2ci...
    • Je ne sais pas si tu as essayé htmx, mais il me semble que cette critique passe à côté, car htmx ne traite pas le même problème que celui que résolvait jQuery, à savoir l’expérience utilisateur JavaScript côté client
      htmx consiste surtout à étendre le paradigme du HTML rendu côté serveur en évitant d’écrire du JavaScript, avec des mises à jour partielles de page plutôt que des rechargements complets
  • Pour en voir davantage sur l’idée des « HTML Web Components », ces articles valent aussi la peine d’être lus
    https://meyerweb.com/eric/thoughts/2023/11/01/blinded-by-the... - « So there you have it: a few thousand words on my journey through coming to understand and work with these fully-Light-DOM web components, otherwise known as custom elements. Now all they need is a catchy name, so we can draw more people to the Light Side of the Web. »
    https://adactio.com/journal/20618 propose un nom qui tient la route

    • Je ne comprends pas bien l’idée principale
      C’est pénible à écrire, si bien qu’on finit par avoir besoin d’un framework léger au-dessus d’un framework intégré comme Lit, et Lit est même plus gros que Preact
      En plus, il ne résout pas de vrais problèmes comme la gestion d’état ou le routage, donc il faudra très probablement ajouter encore d’autres choses
      On peut obtenir des composants réutilisables, mais si l’on se demande si, dans un projet utilisant React, on va intégrer un composant web qui utilise Vue en interne, cela ne tient pas vraiment debout
    • Je suis vraiment ravi de voir un mouvement qui pousse les composants web sans Shadow DOM
      La beauté et l’élégance du Web venaient de sa structure déclarative, qui rendait possibles l’observabilité et la modification
      Le Shadow DOM m’a toujours semblé répondre à un désir très corporate d’ériger des barrières d’encapsulation plus hautes et d’obtenir davantage de certitude, ce qui n’était pas un objectif que je partageais personnellement
      Cet article montre comment le travail avec le Light DOM peut se composer
      J’ai toujours pensé que les composants web ou éléments personnalisés devaient pouvoir modifier eux-mêmes le DOM interne, déplacer leurs enfants et créer du nouveau contenu
      Par exemple, une page ou un framework peut insérer une icône, et un élément d’avatar utilisateur peut insérer un nom ou des éléments décoratifs
      Cela dit, une inquiétude que j’ai avec le Light DOM/les HTML Web Components est que le Shadow DOM apporte certains avantages en matière de performances
      En tant que développeur, je visualise bien le fait qu’il puisse réduire le nombre d’éléments que les sélecteurs CSS doivent parcourir, et j’aimerais pouvoir profiter de cet avantage d’une manière ou d’une autre
      Je suis vraiment content de voir une approche plus légère des éléments personnalisés et des Web Components, et merci pour les liens
    • Pour raccourcir encore le nom plausible, on pourrait peut-être les appeler HTML components
  • L’affirmation « on peut effectuer le rendu avant JavaScript. Les composants React ne pourront jamais faire ça » est difficile à soutenir de façon catégorique : avec le rendu côté serveur, le rendu peut avoir lieu avant le JavaScript côté client.
    Je trouve que l’exemple est trop simple pour illustrer l’argument de l’auteur.
    Un composant web qui gère des changements d’état aurait été un meilleur point de comparaison, et l’argumentation aurait sans doute été plus solide.

    • Bonne remarque ; à l’inverse, on peut aussi considérer que les composants web ne le peuvent pas non plus, puisqu’ils doivent être enregistrés en JavaScript avant le chargement de la page.
      Il existe des solutions d’hydratation, mais elles sont généralement pires, avec des compromis surprenants, et nuisent souvent à la composabilité.
    • Le plus gros problème des Web Components est qu’ils ne sont pas adaptés au rendu côté serveur.
    • Je ne vois pas très bien comment un « HTML Web Component » gérerait les changements d’état.
      Avec le seul exemple qui encapsule une balise img, l’intérêt ne m’a pas vraiment sauté aux yeux ; on peut certes regrouper et réutiliser des éléments communs, mais dès qu’il faut de l’interaction, JavaScript reste nécessaire.
      Même le texte alternatif de l’image dans l’exemple est aujourd’hui généralement dynamique à cause de la localisation, donc sans JavaScript, une partie du contenu peut manquer.
  • J’ai l’impression d’avoir enfin compris l’intérêt des Web Components : https://github.com/kennyfrc/cami.js
    “No Build Steps, No Client-Side Router, No JSX, No Shadow DOM. We want you to build an MPA, with mainly HTML/CSS, and return HTML responses instead of JSON. Then add interactivity as needed.”
    “Declarative templates with lit-html. Supports event handling, attribute binding, composability, caching, and expressions.”

    • La beauté des Web Components, c’est qu’on peut trouver ou créer une classe de base qui se comporte comme on en a besoin.
      Personnellement, j’aime bien les classes dans le style des composants de classe React, avec une machine à états intégrée inspirée de XState.
      https://github.com/codewithkyle/supercomponent/blob/master/s...
    • Je me demande si tu as déjà essayé HTMX.
      L’orientation semble assez similaire, et la communauté de HTMX est peut-être plus grande.
      Si tu l’as essayé, je serais curieux de savoir ce qui t’a semblé manquer.
    • En gros, on remplace JSX par un DSL personnalisé non standard et on appelle ça une victoire.
  • Les « web components » ne sont pas une seule chose, et on ne crée pas non plus « a web component ».
    « Web Components » est le nom de la Web Components API, qui regroupe trois choses.
    Ce que l’on crée réellement, ce sont des éléments personnalisés ; on peut y utiliser Shadow DOM, ou des templates HTML.
    Parmi les trois, le plus important est l’élément personnalisé.
    L’idée centrale étant « créer davantage d’éléments HTML », c’est à vous de décider quels attributs et quelles API JavaScript ils prennent en charge.
    La façon de les placer sur une page, d’interagir avec eux et d’écouter leurs événements est identique à celle des autres éléments HTML.
    Si vous savez écrire des pages web « à l’ancienne », vous savez déjà utiliser des éléments personnalisés ; il ne vous reste qu’à apprendre à les déclarer.

  • J’ai récemment commencé à expérimenter les Web Components sans environnement de build.
    Pas de npm, bun, webpack ou autre, aucune dépendance, et le code est écrit en TypeScript.
    IntelliJ compile automatiquement en JavaScript, et la vue navigateur injecte un petit gestionnaire de détection des changements pour les mises à jour en temps réel pendant le développement.
    Jusqu’ici, je n’ai pas eu de problème.
    Ce qui semble freiner les Web Components, ce sont les HTML Modules.
    Ce serait bien de pouvoir lier un fichier .html, plutôt qu’un fichier .js, pour importer un composant web, mais aujourd’hui, si l’on veut utiliser des templates ou quelque chose d’un peu plus complexe, il faut faire une injection assez laide du genre .innerHtml = \...``.
    Je pensais que ce serait problématique, mais l’IDE analyse plutôt bien les chaînes de templates.

    • Les HTML Modules ont été abandonnés puis supprimés, et remplacés par des imports uniquement en JavaScript.
      Et ce n’est pas non plus la seule raison qui freine les Web Components.
  • J’ai du mal à adhérer à l’idée que « React remplace au lieu d’améliorer »
    Au bout du compte, React rend lui aussi des éléments HTML et y attache des gestionnaires d’événements JavaScript
    Envelopper img dans un composant React ne lui retire pas ses fonctionnalités : on ajoute quelque chose par-dessus, autrement dit on l’améliore
    L’auteur a peut-être travaillé sur d’autres bases de code React, mais d’après mon expérience, quand nous n’avons pas de raison de faire autrement, nous utilisons telles quelles les fonctionnalités intégrées du navigateur
    Peut-être ai-je simplement eu de la chance

    • Il va de soi que toute architecture web finit par rendre des éléments HTML, mais ce n’était pas le sujet
      Le point essentiel est que l’approche des « HTML Web Components », contrairement à React, ne dépend pas de JavaScript pour commencer le rendu
    • À mon avis, la différence centrale dont parle l’article ressemble à ceci
      Du point de vue du rendu par le navigateur, React correspond à « chargement de la page → chargement du composant », tandis que les Web Components sont plus proches de « chargement de la page → rendu de base → chargement du composant »
      Une personne qui désactive JavaScript peut quand même voir quelque chose avec un web component, alors qu’elle peut ne rien voir du tout avec React ; et avec JavaScript, on peut passer à un état de rendu plus avancé
    • Dans certains cas, React rend aussi l’accès aux fonctionnalités intégrées plus difficile
      Par exemple, si l’on assigne onchange à un élément, React ne fournit pas vraiment un événement change, mais quelque chose de plus proche d’un événement input
      En réalité, ce n’est ni l’un ni l’autre : il fournit un événement synthétique plus proche de input que de change
      Si l’on veut réellement change, il faut utiliser une référence vers l’élément et attacher directement le gestionnaire dans un effet
    • Cela dépend de l’architecture de l’application
      Si l’on renvoie du HTML depuis le serveur avec React, envelopper img dans un composant React revient bien à améliorer l’élément existant
      Mais si tout est rendu côté client, cet img ne peut finalement pas être dissocié du composant React
    • En lisant ce passage, j’ai pensé au cas inverse : insérer React dans un autre HTML
      D’après mon expérience, React est excellent quand on lui confie toute la structure de la page de haut en bas, mais cela peut devenir difficile lorsqu’on essaie de l’insérer dans une structure existante, par exemple avec du rendu côté serveur
  • Si l’on cherche une approche durable, la conclusion selon laquelle il faut choisir l’amélioration progressive plutôt que le remplacement correspond aussi à mon expérience
    Grâce à cette philosophie, mes projets web ont duré longtemps avec un minimum de maintenance et de dépendances

  • Un web component doit faire une seule chose, tandis qu’un framework JavaScript se rapproche d’un écosystème complet
    J’ai créé un web component de lecteur vidéo capable d’accepter plusieurs entrées, la plus complexe étant un fichier torrent
    Avec StencilJS [0], j’aurais pu le porter vers Vue/React, mais il était déjà parfaitement utilisable sans cela
    Il suffit d’insérer la balise correspondante avec la classe exportée depuis awesomePlayer.js pour obtenir un lecteur vidéo HTML5 prêt à copier-coller, capable de lire des torrents
    Je recommande aussi fortement, quand c’est possible, d’imiter les éléments HTML existants
    Par exemple, j’ai utilisé src parce que video fonctionne ainsi ; cela permet aux utilisateurs d’interagir avec le composant sans devoir fouiller la documentation
    [0] https://stenciljs.com/

  • J’ai du mal à être d’accord avec l’idée que les composants des frameworks front-end seraient entièrement des remplacements et ne seraient pas composables
    En surface, cela peut sembler vrai, mais dans mes composants j’utilise beaucoup les slots, et leur implémentation est simple tout en se comportant naturellement
    À l’inverse, les Web Components sont généralement démontrés en injectant énormément de code pour construire quelque chose comme un éditeur
    Utiliser des slots dans les Web Components est pénible : il faut attacher beaucoup de nœuds manuellement, manipuler les templates sous forme de chaînes, et, dès que l’on veut faire quelque chose d’un peu complexe, écouter aussi l’événement slotchange
    En substance, cela revient à utiliser l’API DOM ; et si cette API n’était pas aussi affreuse, on ne serait probablement jamais passé à des frameworks front-end comme React
    Je ne suis pas non plus d’accord avec l’argument annexe selon lequel XHTML a échoué parce qu’il n’améliorait pas HTML
    À mon avis, il a échoué parce que les applications devaient être entièrement valides et que cette validation était confiée au client/navigateur
    Si l’on utilisait du vrai XHTML, la moindre petite erreur de balisage aurait cassé la page ; tout le monde validait donc XHTML par souci de compatibilité future, mais aucune entreprise n’aurait pris le risque de voir son activité tomber en panne simplement parce qu’une balise p n’était pas correctement fermée