web-dev-qa-db-fra.com

Avantages et inconvénients de Facebook React vs Web Components (Polymer)

Quels sont les principaux avantages de la spécification React de Facebook par rapport aux spécifications Web Components à venir et vice versa (ou peut-être une comparaison plus pomme à pomme serait-elle à celle de Google Polymère bibliothèque)?

Selon cette conférence JSConf E et la page d'accueil React, les principaux avantages de React) sont:

  • Découplage et cohésion accrue à l'aide d'un modèle de composant
  • Abstraction, composition et expressivité
  • DOM virtuel et événements synthétiques (ce qui signifie essentiellement qu'ils ont complètement réimplémenté le DOM et son système d'événements)
    • Active les éléments d'événement HTML5 modernes sur IE 8
    • Rendu côté serveur
    • Testabilité
    • Liaisons vers SVG, VML et <canvas>

Presque tout ce qui est mentionné est intégré nativement dans les navigateurs via les composants Web, à l'exception de ce concept DOM virtuel (évidemment). Je peux voir comment le DOM virtuel et les événements synthétiques peuvent être bénéfiques aujourd'hui pour prendre en charge les anciens navigateurs, mais ne jette-t-il pas un énorme morceau de code de navigateur natif un peu comme se tirer une balle dans le pied à long terme? En ce qui concerne les navigateurs modernes, n'est-ce pas beaucoup de surcharge/réinvention inutile de la roue?

Voici certaines choses que je pense React que les composants Web prendront soin de vous. Corrigez-moi si je je me trompe.

  • Prise en charge du navigateur natif (lire "garanti d'être plus rapide")
  • Écrire un script dans un langage de script, écrire des styles dans un langage de style, écrire du balisage dans un langage de balisage.
  • Encapsulation de style à l'aide de Shadow DOM
    • React a à la place this , ce qui nécessite d'écrire du CSS en JavaScript. Pas beau.
  • Reliure bidirectionnelle
528
CletusW

Mise à jour: cette réponse semble être assez populaire, j'ai donc pris un peu de temps pour la nettoyer un peu, ajouter de nouvelles informations et clarifier quelques choses que je pensais n'étaient pas assez claires. Veuillez commenter si vous pensez que quelque chose d'autre a besoin d'être clarifié ou mis à jour.

La plupart de vos préoccupations sont vraiment une question d'opinion et de préférence personnelle, mais je vais essayer de répondre aussi objectivement que possible:

Native vs compilé

Écrire JavaScript en JavaScript Vanilla, écrire CSS en CSS, écrire HTML en HTML.

À l'époque, il y avait des débats houleux sur l'opportunité d'écrire l'assemblage natif à la main ou d'utiliser un langage de niveau supérieur comme C pour que le compilateur génère le code d'assemblage pour vous. Même avant cela, les gens refusaient de faire confiance aux assembleurs et préféraient écrire le code machine natif à la main ( et je ne plaisante pas ).

Pendant ce temps, il y a aujourd'hui beaucoup de gens qui écrivent du HTML en Haml ou Jade , CSS en Sass ou Less et JavaScript dans CoffeeScript ou TypeScript . C'est là. Ça marche. Certaines personnes le préfèrent, d'autres non.

Le fait est qu'il n'y a rien de fondamentalement mauvais à pas à écrire JavaScript en Vanilla JavaScript, CSS en CSS et HTML en HTML. C'est vraiment une question de préférence.

DSL internes vs externes

L'encapsulation de style utilisant Shadow DOM React a cela, ce qui nécessite d'écrire du CSS en JavaScript. Pas beau.

Jolie ou pas, elle est certainement expressive. JavaScript est un langage très puissant, beaucoup plus puissant que CSS (même en incluant n'importe lequel des préprocesseurs CSS). Cela dépend en quelque sorte si vous préférez les DSL internes ou externes pour ce genre de choses. Encore une fois, une question de préférence.

(Remarque: je parlais des styles en ligne dans React qui étaient référencés dans la question d'origine.)

Types de DSL - explication

Mise à jour: En lisant ma réponse quelque temps après l'avoir écrite, je pense que je dois expliquer ce que je veux dire ici. DSL est un langage spécifique au domaine et il peut être soit interne (en utilisant la syntaxe du langage hôte comme JavaScript - comme par exemple React sans JSX, ou comme les styles en ligne dans React mentionné ci-dessus) ou il peut être externe (en utilisant une syntaxe différente de la langue de l'hôte - comme dans cet exemple, cela inclurait CSS (une DSL externe) à l'intérieur de JavaScript).

Cela peut prêter à confusion car certains documents utilisent des termes différents de "interne" et "externe" pour décrire ces types de DSL. Parfois, "incorporé" est utilisé au lieu de "interne" mais le mot "incorporé" peut signifier différentes choses - par exemple Lua est décrit comme "Lua: un langage incorporé extensible" où incorporé n'a rien à voir avec DSL intégré (interne) (dans ce sens, c'est tout le contraire - un DSL externe) mais cela signifie qu'il est intégré dans le même sens que, disons, SQLite est une base de données intégrée. Il y a même eLua où "e" signifie "embarqué" dans un troisième sens - qu'il est destiné à systèmes embarqués ! C'est pourquoi je n'aime pas utiliser le terme "DSL intégré" car des choses comme eLua peuvent être des "DSL" qui sont "intégrées" dans deux sens différents sans être du tout "DSL intégré"!

Pour aggraver les choses, certains projets introduisent encore plus de confusion dans le mix. Par exemple. les modèles Flatiron sont décrits comme "sans DSL" alors qu'en fait, ce n'est qu'un exemple parfait d'une DSL interne avec une syntaxe comme: map.where('href').is('/').insert('newurl');

Cela étant dit, lorsque j'ai écrit "JavaScript est un langage très puissant, beaucoup plus puissant que CSS (même avec n'importe lequel des préprocesseurs CSS). Cela dépend en quelque sorte si vous préférez les DSL internes ou externes pour ce genre de choses. Encore une fois, une question de préférence. " Je parlais de ces deux scénarios:

Une:

/** @jsx React.DOM */
var colored = {
  color: myColor
};
React.renderComponent(<div style={colored}>Hello World!</div>, mountNode);

Deux:

// SASS:
.colored {
  color: $my-color;
}
// HTML:
<div class="colored">Hello World!</div>

Le premier exemple utilise ce qui a été décrit dans la question comme: "écrire du CSS en JavaScript. Pas joli." Le deuxième exemple utilise Sass. Bien que je convienne que l'utilisation de JavaScript pour écrire du CSS peut ne pas être jolie (pour certaines définitions de "joli") mais il y a un avantage à le faire.

Je peux avoir des variables et des fonctions dans Sass mais sont-elles de portée lexicale ou de portée dynamique? Sont-ils typés de manière statique ou dynamique? Fortement ou faiblement? Et les types numériques? Type de coersion? Quelles valeurs sont vraies et lesquelles sont fausses? Puis-je avoir des fonctions d'ordre supérieur? Récursivité? Appels de queue? Fermetures lexicales? Sont-ils évalués dans l'ordre normal ou dans l'ordre d'application? Y a-t-il une évaluation paresseuse ou impatiente? Les arguments des fonctions sont-ils transmis par valeur ou par référence? Sont-ils mutables? Immuable? Persistant? Et les objets? Des classes? Des prototypes? Héritage?

Ce ne sont pas des questions triviales et pourtant je dois y répondre si je veux comprendre le code Sass ou Less. Je connais déjà ces réponses pour JavaScript, cela signifie donc que je comprends déjà chaque DSL interne (comme les styles en ligne dans React) à ces mêmes niveaux, donc si j'utilise React alors je ne dois connaître qu'un seul ensemble de réponses à ces (et beaucoup d'autres questions similaires), tandis que lorsque j'utilise par exemple. Sass et guidon alors je dois connaître trois ensembles de ces réponses et comprendre leurs implications.

Cela ne veut pas dire qu'une façon ou l'autre est toujours meilleure, mais chaque fois que vous introduisez une autre langue dans le mélange, vous payez un prix qui peut ne pas être aussi évident à première vue, et ce prix est la complexité.

J'espère avoir clarifié un peu ce que je voulais dire à l'origine.

Liaison de données

Reliure bidirectionnelle

C'est un sujet vraiment intéressant et en fait aussi une question de préférence. Deux voies n'est pas toujours mieux qu'une voie. Il s'agit de savoir comment vous souhaitez modéliser l'état mutable dans votre application. J'ai toujours considéré les liaisons bidirectionnelles comme une idée quelque peu contraire aux principes de la programmation fonctionnelle, mais la programmation fonctionnelle n'est pas le seul paradigme qui fonctionne, certaines personnes préfèrent ce type de comportement et les deux approches semblent fonctionner assez bien dans la pratique. Si vous êtes intéressé par les détails des décisions de conception liées à la modélisation de l'état dans React alors regardez l'exposé de Pete Hunt (lié à dans la question) et - le discours de Tom Occhino et Jordan Walke qui l'expliquent très bien à mon avis.

Mise à jour: Voir aussi une autre conférence de Pete Hunt: Soyez prévisible, pas correct: programmation DOM fonctionnelle .

Mise à jour 2: Il convient de noter que de nombreux développeurs argumentent contre les données bidirectionnelles flux, ou liaison bidirectionnelle, certains l'appellent même un anti-modèle. Prenons par exemple l'architecture d'application Flux qui évite explicitement le modèle MVC (qui s'est avéré difficile à mettre à l'échelle pour les grands Facebook et Instagram applications) en faveur d'un flux de données strictement unidirectionnel (voir le Hacker Way: repenser le développement d'applications Web sur Facebook conférence de Tom Occhino, Jing Chen et Pete Hunt pour une bonne introduction). En outre, de nombreuses critiques contre AngularJS (le framework Web le plus populaire basé sur le modèle MVC, connu pour la liaison de données bidirectionnelle) incluent des arguments contre ce flux de données bidirectionnel, voir:

Mise à jour 3: Un autre article intéressant qui explique bien certains des problèmes abordés ci-dessus est Déconstruire le flux de ReactJS - Ne pas utiliser MVC avec ReactJS par Mikael Brassman, auteur de RefluxJS (une bibliothèque simple pour l'architecture d'application de flux de données unidirectionnelle inspirée de Flux).

Mise à jour 4: Ember.js s'éloigne actuellement de la liaison de données bidirectionnelle et dans les versions futures, elle en sera une -way par défaut. Voir: The Future of Ember conférence de Stefan Penner du Embergarten Symposium à Toronto le 15 novembre 2014.

Mise à jour 5: Voir aussi: The Road to Ember 2.0 RFC - discussion intéressante dans la pull request de Tom Dale :

"Lorsque nous avons conçu la couche de modèles d'origine, nous avons pensé que rendre toutes les liaisons de données bidirectionnelles n'était pas très nocif: si vous ne définissez pas une liaison bidirectionnelle, c'est une liaison unidirectionnelle de facto!

Nous avons depuis réalisé (avec l'aide de nos amis de React) que les composants veulent pouvoir transmettre des données à leurs enfants sans avoir à se méfier des mutations capricieuses.

De plus, la communication entre les composants est souvent exprimée le plus naturellement sous forme d'événements ou de rappels . Cela est possible dans Ember, mais la dominance des liaisons de données bidirectionnelles conduit souvent les gens à utiliser des liaisons bidirectionnelles comme canal de communication . Les développeurs expérimentés Ember ne font pas (généralement) cette erreur, mais c'est facile à faire. " [italiques ajoutés]

Native vs VM

Prise en charge du navigateur natif (lire "garanti d'être plus rapide")

Maintenant enfin quelque chose qui n'est pas une question d'opinion.

En fait, ici, c'est exactement l'inverse. Bien sûr, le code "natif" peut être écrit en C++ mais selon vous, dans quoi les moteurs JavaScript sont-ils écrits?

En fait, les moteurs JavaScript sont vraiment incroyables dans les optimisations qu'ils utilisent aujourd'hui - et non seulement la V8, SpiderMonkey et même Chakra brille de nos jours. Et gardez à l'esprit qu'avec les compilateurs JIT, le code n'est pas seulement aussi natif que possible, mais il existe également des opportunités d'optimisation du temps d'exécution qui sont tout simplement impossibles à faire dans tout code compilé statiquement.

Lorsque les gens pensent que JavaScript est lent, cela signifie généralement que JavaScript accède au DOM. Le DOM est lent. Il est natif, écrit en C++ et pourtant il est lent comme l'enfer à cause de la complexité qu'il doit implémenter.

Ouvrez votre console et écrivez:

console.dir(document.createElement('div'));

et voyez combien de propriétés un élément div vide qui n'est même pas attaché au DOM doit implémenter. Ce ne sont que les propriétés de premier niveau qui sont des "propriétés propres", c'est-à-dire. non hérité de la chaîne prototype:

aligner, en attente, en échange de volume, en attente de mise à jour, en suspension, en soumission, en installation, en spectacle, en sélection, en recherche, en recherche, en défilement, en redimensionnement, en réinitialisation, en échange, en progrès, en affichage, en affichage, en pause, en mouvement, en mouvement, en mouvement, en mouvement onmouseenter, onmousedown, onloadstart, onloadedmetadata, onloadeddata, onload, onkeyup, onkeypress, onkeydown, oninvalid, oninput, onfocus, onerror, onended, onemptied, ondurationchange, ondrop, ondragstart, ondragover, ondragleave, ondragcl oncontextmenu, onclose, onclick, onchange, oncanplaythrough, oncanplay, oncancel, onblur, onabort, orthographe, isContentEditable, contentEditable, externalText, innerText, accessKey, masqué, webkitdropzone, draggable, tabIndex, dir, translE, langCount, title firstElementChild, children, nextElementSibling, previousElementSibling, onwheel, onwebkitfullscreenerror, onwebkitfullscreenchange, onsele ctstart, onsearch, onpaste, oncut, oncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, dataset, classList, className, externalHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, offsetTef, clientWidth offsetTop, offsetLeft, localName, prefix, namespaceURI, id, style, attributes, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeName

Beaucoup d'entre eux sont en fait des objets imbriqués - pour voir les propriétés de deuxième niveau (propres) d'un div natif vide dans votre navigateur, voir ce violon .

Je veux dire sérieusement, onvolumechange propriété sur chaque nœud div unique? Est-ce une erreur? Non, c'est juste une version traditionnelle du modèle d'événement DOM niveau 0 d'un des gestionnaires d'événements "qui doit être pris en charge par tous les éléments HTML , en tant qu'attributs de contenu et attributs IDL "[non souligné dans l'original] dans Section 6.1.6.2 de la spécification HTML du W3C - aucun moyen de le contourner .

En attendant, ce sont les propriétés de premier niveau d'un faux DOM-div dans React:

accessoires, _ propriétaire, _lifeCycleState, _pendingProps, _pendingCallbacks, _pendingOwner

Quelle différence, non? En fait, c'est tout l'objet sérialisé en JSON ( LIVE DEMO ), parce que vous en fait peut le sérialiser en JSON car il ne contient aucune référence circulaire - quelque chose d'impensable dans le monde du DOM natif ( où il lèverait simplement une exception ):

{
  "props": {},
  "_owner": null,
  "_lifeCycleState": "UNMOUNTED",
  "_pendingProps": null,
  "_pendingCallbacks": null,
  "_pendingOwner": null
}

C'est à peu près la principale raison pour laquelle React peut être plus rapide que le navigateur natif DOM - car il n'a pas à implémenter ce gâchis .

Voir cette présentation de Steven Luscher pour voir ce qui est plus rapide: un DOM natif écrit en C++ ou un faux DOM écrit entièrement en JavaScript. C'est une présentation très juste et divertissante.

Mise à jour: Ember.js dans les futures versions utilisera un DOM virtuel fortement inspiré par React pour améliorer perfomance. Voir: The Future of Ember conférence de Stefan Penner du Embergarten Symposium à Toronto le 15 novembre 2014.

Pour résumer: les fonctionnalités des composants Web comme les modèles, la liaison de données ou les éléments personnalisés auront de nombreux avantages par rapport à React mais jusqu'à ce que le modèle d'objet de document lui-même soit considérablement simplifié, les performances ne seront pas de celles-là.

Mise à jour

Deux mois après avoir posté ces réponses, il y a eu des nouvelles pertinentes ici. Comme je viens d'écrire sur Twitter , la dernière version de l'éditeur de texte Atom écrit par GitHub en JavaScript utilise Facebook React pour obtenir de meilleures performances même si selon Wikipedia "Atom est basé sur Chromium et écrit en C++" donc il a le contrôle total de l'implémentation native du C++ DOM (voir Le noyau d'Atome ) et est garanti pour prendre en charge les composants Web car il est livré avec son propre navigateur Web. Ce n'est qu'un exemple très récent d'un projet du monde réel qui aurait pu utiliser tout autre type d'optimisation généralement indisponible pour les applications Web et pourtant il a choisi d'utiliser React qui est lui-même écrit en JavaScript, pour atteindre meilleures performances, même si Atom n'a pas été construit avec React pour commencer, ce n'était donc pas un changement trivial.

Mise à jour 2

Il y a ne comparaison intéressante par Todd Parker utilisant WebPagetest pour comparer les performances de TodoMVC exemples écrits en angulaire, dorsale, braise, polymère, CanJS, YUI , Knockout, React et Shoestring. C'est la comparaison la plus objective que j'ai vue jusqu'à présent. Ce qui est important ici, c'est que tous les exemples respectifs ont été écrits par des experts dans tous ces cadres, ils sont tous disponibles sur GitHub et peuvent être améliorés par quiconque pense qu'une partie du code pourrait être optimisé pour courir plus vite.

Mise à jour 3

Ember.js dans les futures versions comprendra un certain nombre de fonctionnalités de React qui sont discutées ici (y compris un DOM virtuel et une liaison de données unidirectionnelle, pour n'en nommer que quelques-uns), ce qui signifie que les idées qui sont issues de React migrent déjà vers d'autres frameworks. Voir: The Road to Ember 2.0 RFC - discussion intéressante dans la demande de tirage par Tom Dale (Date de début: 2014-12-03): "In Ember 2.0, nous adopterons un "DOM virtuel" et un modèle de flux de données qui englobe les meilleures idées de React et simplifie la communication entre les composants. "

De plus, Angular.js 2. implémente un grand nombre des concepts discutés ici.

Mise à jour 4

Je dois développer quelques points pour répondre à ce commentaire d'Igwe Kalu:

"il n'est pas judicieux de comparer React (JSX ou la sortie de la compilation) à du JavaScript simple, quand React se réduit finalement à du JavaScript simple. [...] Quelle que soit la stratégie React les utilisations pour l'insertion de DOM peuvent être appliquées sans utiliser React. Cela dit, cela n'ajoute aucun avantage particulier lors de l'examen de la fonctionnalité en question autre que la commodité. " (commentaire complet ici )

Au cas où ce ne serait pas assez clair, dans une partie de ma réponse, je compare les performances de fonctionner directement sur le DOM natif (implémenté en tant qu'objets Host dans le navigateur) vs le faux React/virtual DOM (implémenté en JavaScript). Le point que j'essayais de faire est que le DOM virtuel implémenté en JavaScript peut surpasser le réel DOM implémenté en C++ et pas qui React peut surpasser JavaScript (ce qui évidemment n'aurait pas beaucoup de sens car il est écrit en JavaScript). Mon point était que le code C++ "natif" n'est pas toujours garanti d'être plus rapide que le JavaScript "non natif". Utiliser React pour illustrer ce point n'était qu'un exemple.

Mais ce commentaire a touché une question intéressante. Dans un sens, il est vrai que vous n'avez besoin d'aucun framework (React, Angular ou jQuery) pour quelque raison que ce soit (comme les performances, la portabilité, les fonctionnalités) car vous pouvez toujours recréer ce que le framework fait pour vous. et réinventer la roue - si vous pouvez justifier le coût, bien sûr.

Mais - comme l'a si bien dit Dave Smith Comment passer à côté de la comparaison des performances du framework web : "Lors de la comparaison de deux frameworks web, la question n'est pas can mon application sera rapide avec le framework X. La question est sera mon application sera rapide avec le framework X. "

Dans ma réponse de 2011 à: Quelles sont les raisons techniques empiriques de ne pas utiliser jQuery J'explique un problème similaire, qu'il n'est pas impossible d'écrire du code de manipulation DOM portable sans une bibliothèque comme jQuery, mais que les gens le font rarement.

Lorsqu'ils utilisent des langages de programmation, des bibliothèques ou des frameworks, les gens ont tendance à utiliser les façons de faire les plus pratiques ou idiomatiques, pas les plus parfaites mais les plus gênantes. La vraie valeur de bons cadres rend facile ce qui serait autrement difficile à faire - et le secret rend les bonnes choses commodes. Le résultat est toujours d'avoir exactement la même puissance à votre disposition que la forme la plus simple de calcul lambda ou la machine de Turing la plus primitive, mais l'expressivité relative de certains concepts signifie que ces mêmes concepts ont tendance à s'exprimer plus facilement ou pas du tout, et que les bonnes solutions ne sont pas seulement possibles, mais en fait largement mises en œuvre.

Mise à jour 5

React + Performance =? l'article de Paul Lewis de juillet 2015 montre un exemple où React est plus lent que Vanilla JavaScript écrit à la main pour une liste infinie de photos Flickr, ce qui est particulièrement significatif sur le mobile. Cet exemple montre que tout le monde doit toujours tester les performances pour un cas d'utilisation spécifique et des plates-formes et appareils cibles spécifiques.

Merci à Kevin Lozandier pour en le portant à mon attention .

671
rsp

Les gars de React ont un assez bonne explication sur la comparaison entre React et les composants Web:

Essayer de comparer et de contraster React avec WebComponents entraîne inévitablement des conclusions spécieuses, car les deux bibliothèques sont conçues pour résoudre des problèmes différents. Les composants Web fournissent une forte encapsulation pour les composants réutilisables, tandis que React fournit une bibliothèque déclarative qui maintient le DOM en synchronisation avec vos données. Les deux objectifs sont complémentaires; les ingénieurs peuvent mélanger et assortir les technologies. En tant que développeur, vous êtes libre d'utiliser React dans vos WebComponents, ou d'utiliser WebComponents dans React, ou les deux.

17
Erik Kaplun

Le polymère est génial. React est génial. Ce n'est pas la même chose.

Polymer est une bibliothèque pour la création de composants Web rétrocompatibles.

React est le V dans MVC. C'est la vue, et rien d'autre. Pas en soi du moins.

React n'est pas un framework.

React + Flux + Node + (Gulp or Grunt) est plus comparable à un framework, mais 3 de ces choses ne font pas du tout partie de react.

Il existe de nombreuses technologies, modèles et styles architecturaux que réagissent les développeurs, mais réagir lui-même n'est pas un cadre.

C'est triste que personne n'ait pris le temps de dire la chose la plus simple possible, qu'il ne fallait pas les comparer. Ils ont un certain chevauchement, mais ils sont plus différents que les mêmes.

Ils vous permettent tous deux de définir des composants Web, mais de différentes manières. Au-delà, ce sont des outils très très différents.

17
Robotsushi

Une autre réponse sur un point en particulier:

Écrire JavaScript en Vanilla JavaScript, écrire CSS en CSS, écrire HTML en HTML.

Rien ne vous empêche d'écrire du Javascript dans, disons, CoffeeScript, TypeScript, ClojureScript ou quoi que ce soit d'autre. C'est purement une question de préférence.

HTML est le meilleur DSL pour statique documents HTML. Mais il ne fournit rien pour le HTML dynamique. Et dans le navigateur, la meilleure langue pour rendre HTML dynamique est Javascript, pas du HTML pur avec une manipulation DOM ad-hoc Javascript ou un langage de modèle comme les guidons qui ne sont même pas des demi-langues.

Pour CSS, si votre CSS est statique, vous l'écrivez comme d'habitude. S'il doit être dynamique en fonction de certaines valeurs d'exécution, c'est la même chose que HTML: Javascript est le meilleur moyen de le rendre dynamique.

15
DjebbZ

Je n'ai pas utilisé de composants Web, mais il semble qu'ils nécessitent que vous ajoutiez une logique de mutation codée manuellement aux gestionnaires d'événements.

extrait de Polymer:

 <script>
   Polymer({
     counterChanged: function() {
       this.$.counterVal.classList.add('highlight');
     },
 ...

L'intérêt de React est de réduire la complexité en éliminant la logique de mutation. Au lieu de cela, vous régénérez naïvement un DOM virtuel et laissez l'algorithme diff de React déterminer ce qui doit changer dans le vrai DOM.

6
limscoder

Je pense que le plus gros inconvénient de React à mon avis est qu'il n'est pas basé sur les standards du Web. React est un outil très puissant en ce moment, mais parce qu'il contourne autant de ce que le navigateur fournit chaque fois que possible, les décisions qui semblaient avoir du sens maintenant n'auront probablement pas de sens dans quelques années comme les navigateurs ' les installations intégrées continuent de s'améliorer. Je voudrais donc parler de cela et de son impact sur quelques aspects différents des applications Web.

Performances

Les gens aiment soutenir que l'avantage de React est qu'il réinvente complètement le DOM et le modèle d'événement, et que le DOM standard existant est lourd et cher et quoi, mais, au final, je n'ai pas trouvé les performances de React pour être meilleur que ce que je peux tirer d'une application Backbone ou Polymer bien écrite. En fait, dans la plupart de mon expérience professionnelle, les performances de React ont en fait été un peu pires. Cela ne veut pas dire que React est lent ... Ce n'est tout simplement pas le choix de performances de Edge saignant que nous pensions tous que c'était avant de mettre la main dessus.

Dans la réponse de rsp, il souligne que le modèle DOM de React pour un div est beaucoup plus léger que le div natif DOM, et c'est certainement vrai. Cependant, pour que React soit utile, ce div "virtuel" doit finir par devenir un vrai div à un moment donné. Donc, dans ma vision du monde, il ne s'agit pas d'une div React contre une div native. C'est un React div + un div natif vs juste un div natif. Le surdébit de la version React du DOM n'est pas anodin, et si les normes suppriment un jour certains de ces attributs inutiles et permettent aux nœuds DOM natifs d'être beaucoup plus légers, soudain, ce surdos va sembler très cher.

Dans l'un de mes précédents emplois, nous avons eu quelques applications dans Polymer et d'autres dans React. L'une des premières applications de Polymer a fini par être réécrite en React parce que c'était ce que la société avait en standard et sur la base des mesures que j'ai prises ReactLa version _ de cette même application s'est avérée utiliser environ 30% de mémoire en plus que la version Polymer, et bien que la différence soit marginale, la version Polymer a été rendue en moins de temps également. Une chose à considérer ici est que nous parlons d'applications écrites par des personnes, et que les personnes ne sont pas parfaites, il est donc possible que l'implémentation de [React de cette application ne profite pas de tout React est capable de. Mais je pense qu'au moins une partie de cela a à voir avec la surcharge React résultant de sa propre version du DOM.

React réinvente l'intégralité du DOM à l'aide de son propre modèle, puis l'utilise pour une optimisation des performances majeure. Une vue est rendue dans un DOM virtuel, et celle-ci est projetée dans le vrai DOM. Lorsqu'il y a un changement et que la vue doit être mise à jour, la vue est à nouveau restituée dans un DOM virtuel, et cet arbre est différent de l'arbre précédent pour déterminer quels nœuds doivent être modifiés dans le DOM réel pour refléter ce changement dans la vue. Bien qu'il s'agisse d'une approche très intelligente pour effectuer des mises à jour DOM efficaces, il est difficile de maintenir toutes ces arborescences DOM virtuelles et de les différencier pour déterminer ce qu'il faut changer dans le vrai DOM. À l'heure actuelle, cette surcharge est largement compensée par les avantages en termes de performances, mais à mesure que le DOM natif s'améliore avec le temps, l'échelle se déplace dans l'autre sens. Je m'inquiète de la façon dont les applications [React pourraient vieillir, et si dans 3 ans elles seront beaucoup plus lentes que celles qui traitent le DOM plus directement. Cette approche du DOM virtuel est un peu un marteau, et d'autres bibliothèques comme Polymer ont pu mettre en œuvre des approches très efficaces pour traiter le DOM d'une manière beaucoup plus subtile.

Mise à jour pour les performances: L'une des bibliothèques que j'ai rencontrées il y a quelque temps fait ce que je pense être un meilleur travail de gestion des mises à jour du DOM. Il s'agit de la bibliothèque Incremental Dom de Google, et je pense que le fait qu'il fonctionne avec le dom en place et n'a pas à créer une `` copie virtuelle '' est une approche beaucoup plus propre, avec beaucoup moins de mémoire. Voir plus ici: http://google.github.io/incremental-dom/#about

Composants déclaratifs vs impératifs

L'une des choses que vous entendez toujours apparaître lorsque vous parlez de composant votre application est tous les avantages de la déclaration de vos composants. Dans la vision du monde de React, tout est agréable et déclaratif. Vous écrivez JavaScript qui retourne le balisage et React colle le tout pour vous. Et c'est très bien si vous avez affaire à une toute nouvelle application qui utilise uniquement React et rien d'autre. Vous pouvez écrire un composant et tant que vous êtes à l'intérieur d'un morceau appartenant au React du DOM, c'est aussi simple que de mettre cette balise sur la page pour consommer votre composant.

Mais dès que vous allez prendre ces composants et les utiliser en dehors de React, les choses deviennent beaucoup plus compliquées. Étant donné que la façon dont les composants React sont transformés en balises est complètement en dehors des normes Web, rien d'autre que React ne sait comment vous donner un moyen déclaratif de consommer ces composants. Si je veux mettre des composants React dans une vue Backbone existante qui utilise des modèles Handlebars, vous devez rendre un div factice dans votre modèle avec une classe ou un ID que vous pouvez utiliser comme poignée, puis écrire impérativement JavaScript dans trouver ce div factice et y monter votre composant. Vous avez une application Express.js qui utilise des modèles côté serveur? Eh bien, c'est la même chanson et la même danse. Une page JSP? Vous riez, mais il y a une tonne d'applications qui les utilisent encore. À moins que vous ne soyez une sorte de démarrage sans code existant, vous devrez écrire de la plomberie afin de réutiliser vos composants React dans de nombreuses applications. Pendant ce temps, Polymer réalise les composants via la norme Web Components, et en utilisant la spécification d'élément personnalisé, Polymer est capable de créer des composants que le navigateur sait utiliser de manière native. Je peux mettre un composant Polymer dans une page JSP, un modèle Express.js, une vue ASP.NET, une vue Backbone ... à l'intérieur d'un composant React même. Littéralement partout où vous pouvez utiliser HTML, vous pouvez consommer un composant Polymer. Les personnes qui conçoivent pour la réutilisation se tournent vers les normes Web, car les normes sont le contrat qui facilite la compatibilité des choses. YouTube continue de créer de plus en plus de choses dans Polymer (source: http://react-etc.net/entry/youtube-is-being-rebuilt-on-web-components-and- polymère ), et je ne peux qu'imaginer l'aspect normalisé de Polymer en est la raison. Ce lecteur YouTube au milieu de la page YouTube pourrait être transformé en un composant qui prend une source de contenu en tant que propriété, et soudainement, toute personne qui souhaite intégrer le lecteur YouTube dans sa page peut littéralement utiliser exactement le même code de lecteur que YouTube utilise , et ils peuvent le faire simplement en collant une balise dans leur page.

Résumé

Je peux voir qu'il y a certainement des aspects attrayants de React en ce moment. Si tout ce que vous utilisez est React, vous pouvez créer des widgets et des composants et les réutiliser de manière déclarative partout. Mais je pense que React aurait été beaucoup mieux s'il avait utilisé certaines des normes des composants Web pour réaliser ce qu'il fait, au lieu de partir et de créer un navigateur dans un navigateur et un mécanisme complexe pour tout synchroniser.

6
Dogs