Pros y contras de React de Facebook frente a componentes web (polímero)

521

¿Cuáles son los principales beneficios de React de Facebook sobre la próxima especificación de componentes web y viceversa (o tal vez una comparación más entre manzanas sería con la biblioteca Polymer de Google )?

Según esta charla de JSConf EU y la página de inicio de React, los principales beneficios de React son:

  • Desacoplamiento y mayor cohesión utilizando un modelo de componente
  • Abstracción, Composición y Expresividad
  • DOM virtual y eventos sintéticos (lo que básicamente significa que re-implementaron completamente el DOM y su sistema de eventos)
    • Permite material de eventos HTML5 moderno en IE 8
    • Representación del lado del servidor
    • Testabilidad
    • Enlaces a SVG, VML y <canvas>

Casi todo lo mencionado se está integrando en los navegadores de forma nativa a través de Web Components, excepto este concepto DOM virtual (obviamente). Puedo ver cómo el DOM virtual y los eventos sintéticos pueden ser beneficiosos hoy en día para admitir navegadores antiguos, pero ¿no está arrojando una gran cantidad de código de navegador nativo como dispararse en el pie a largo plazo? En lo que respecta a los navegadores modernos, ¿no se trata de una sobrecarga / reinvención innecesaria de la rueda?

Aquí hay algunas cosas que creo que falta React que Web Components se encargará de usted. Corrígeme si estoy equivocado.

  • Soporte de navegador nativo (lea "garantizado para ser más rápido")
  • Escriba guiones en un lenguaje de guiones, escriba estilos en un lenguaje de estilo, escriba marcado en un lenguaje de marcado.
  • Encapsulación de estilo usando Shadow DOM
    • React en cambio tiene esto , que requiere escribir CSS en JavaScript. No es bonito.
  • Enlace bidireccional
CletusW
fuente
12
Wrt. Dos vías vinculantes. Esta característica es problemática a escala. En casos triviales funciona bien, pero en los casos del mundo real, por lo general, encuentras que para mantener el código manejable necesitas un modelo de vista para enlazar, en lugar de enlazar con el modelo real, lo que hace que el enlace bidireccional sea mucho menos útil que Al principio parecía. Creo que puede ser una ventaja de React que no proporciona enlace bidireccional porque obliga a una arquitectura de flujo de datos adecuada.
Joeri Sebrechts
8
He mirado en React, Angular y Knockout. Considero que Knockout es el "más limpio" en términos de separación de plantillas ui, datos y enlaces. Quería que me gustara reaccionar, pero al tratar de crear un Combobox simple, me di cuenta de que estaba escribiendo mucho más código y mezclando la lógica de representación con plantillas html ... mucho más de lo que lo haría usando algo como html / jina2. Me parece que estas bibliotecas / apis nos están moviendo hacia atrás, no hacia adelante. Lo mejor de React es la manipulación de dom virtual, pero puedo ver que llegará a otros frameworks establecidos más temprano que tarde.
mike01010
41
Estoy muy sorprendido (¡y también complacido!) De que esta pregunta no se haya cerrado como "principalmente basada en la opinión".
iconoclasta
44
No es posible escribir "script en un lenguaje de script" y "marcado en un lenguaje de marcado" si está haciendo plantillas de cualquier tipo. Angular, polímero, etc. utiliza una plantilla DSL incrustada en HTML. React utiliza una plantilla DSL integrada en JS (JSX). El problema con la incorporación de un DSL en HTML es cómo establecer el alcance para obtener valores del JS. Esto lleva al complejo sistema $ scope de Angular. En JSX, por otro lado, el alcance de las variables en las plantillas es solo el alcance de JS, lo encuentro mucho menos confuso.
Andy
3
Por el momento, los componentes de React (a menos que estén mal escritos) serían más rápidos que lo mismo en cualquier marco de trabajo vinculado al DOM. El v-dom y la magia diferente es el USP de reaccionar. Mi punto es: ¿por qué los navegadores no crean una diferencia como esa en su conjunto de características nativas? Lo que los detiene, y si nada (los detiene), entonces el liderazgo de React probablemente será de corta duración.
fasttrainofthoughts

Respuestas:

664

Actualización:  esta respuesta parece ser bastante popular, así que me tomé un tiempo para limpiarla un poco, agregar información nueva y aclarar algunas cosas que pensé que no estaban lo suficientemente claras. Comente si cree que algo más necesita aclaraciones o actualizaciones.

La mayoría de sus preocupaciones son realmente una cuestión de opinión y preferencia personal, pero trataré de responder de la manera más objetiva posible:

Nativo vs. Compilado

Escriba JavaScript en JavaScript vainilla, escriba CSS en CSS, escriba HTML en HTML.

En el pasado hubo debates candentes sobre si uno debería escribir  ensamblado nativo a mano o usar un lenguaje de nivel superior como C para hacer que el compilador genere código de ensamblado para usted. Incluso antes de eso, la gente se negaba a confiar en los ensambladores y prefería escribir código máquina nativo a mano ( y no estoy bromeando ).

Mientras tanto, hoy en día hay muchas personas que escriben HTML en Haml o Jade , CSS en Sass o Less y JavaScript en CoffeeScript o TypeScript . Está allá. Funciona. Algunas personas lo prefieren, otras no.

El punto es que no hay nada fundamentalmente incorrecto en no escribir JavaScript en JavaScript vainilla, CSS en CSS y HTML en HTML. Es realmente una cuestión de preferencia.

DSL internos versus externos

 En cambio, la encapsulación de estilo con Shadow DOM React tiene esto, que requiere escribir CSS en JavaScript. No es bonito.

Bonita o no, sin duda es expresiva. JavaScript es un lenguaje muy poderoso, mucho más poderoso que CSS (incluso incluyendo cualquiera de los preprocesadores CSS). Depende de si prefiere DSL internas o externas para ese tipo de cosas. De nuevo, una cuestión de preferencia.

(Nota: estaba hablando de los estilos en línea en React a los que se hizo referencia en la pregunta original).

Tipos de DSL - explicación

Actualización: leyendo mi respuesta un tiempo después de escribirla, creo que necesito explicar lo que quiero decir aquí. DSL es un lenguaje específico de dominio y puede ser interno (usando la sintaxis del lenguaje anfitrión como JavaScript, como por ejemplo React sin JSX, o como los estilos en línea en React mencionados anteriormente) o puede ser externo (usando una sintaxis diferente que el idioma del host, como en este ejemplo estaría alineado CSS (un DSL externo) dentro de JavaScript).

Puede ser confuso porque algunas publicaciones usan términos diferentes a "interno" y "externo" para describir ese tipo de DSL. A veces se usa "incrustado" en lugar de "interno", pero la palabra "incrustado" puede significar cosas diferentes, por ejemplo, Lua se describe como "Lua: un lenguaje incrustado extensible" donde incrustado no tiene nada que ver con DSL incrustado (interno) en qué sentido es todo lo contrario: un DSL externo) pero significa que está incrustado en el mismo sentido que, por ejemplo, SQLite es una base de datos incrustada. Incluso hay eLua donde "e" significa "integrado" en un tercer sentido: que está destinado a sistemas integrados! ¡Es por eso que no me gusta usar el término "DSL incrustado" porque cosas como eLua pueden ser "DSL" que están "incrustadas" en dos sentidos diferentes sin ser un "DSL incrustado" en absoluto!

Para empeorar las cosas, algunos proyectos introducen aún más confusión en la mezcla. P.ej. Las plantillas Flatiron se describen como "sin DSL" mientras que, de hecho, es solo un ejemplo perfecto de un DSL interno con una sintaxis como:map.where('href').is('/').insert('newurl');

Dicho esto, cuando escribí "JavaScript es un lenguaje muy poderoso, mucho más poderoso que CSS (incluso incluyendo cualquiera de los preprocesadores CSS). Depende de si prefieres DSLs internos o externos para ese tipo de cosas. Nuevamente, una cuestión de preferencia ". Estaba hablando de esos dos escenarios:

Uno:

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

Dos:

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

El primer ejemplo utiliza lo que se describió en la pregunta como: "escribir CSS en JavaScript. No es bonito". El segundo ejemplo usa Sass. Si bien estoy de acuerdo en que usar JavaScript para escribir CSS puede no ser bonito (para algunas definiciones de "bonito"), pero hay una ventaja de hacerlo.

Puedo tener variables y funciones en Sass, pero ¿tienen un alcance léxico o un alcance dinámico? ¿Se escriben estática o dinámicamente? ¿Fuerte o débil? ¿Qué pasa con los tipos numéricos? Tipo coersion? ¿Qué valores son verdaderos y cuáles son falsos? ¿Puedo tener funciones de orden superior? Recursividad? ¿Llamadas de cola? Cierres léxicos? ¿Se evalúan en orden normal u orden aplicativo? ¿Hay una evaluación perezosa o ansiosa? ¿Se pasan los argumentos a las funciones por valor o por referencia? ¿Son mutables? ¿Inmutable? ¿Persistente? ¿Qué hay de los objetos? Clases? Prototipos? ¿Herencia?

Esas no son preguntas triviales y, sin embargo, tengo que saber las respuestas a ellas si quiero entender el código Sass o Less. Ya conozco esas respuestas para JavaScript, por lo que significa que ya entiendo cada DSL interno (como los estilos en línea en React) en esos mismos niveles, por lo que si uso React, tengo que saber solo un conjunto de respuestas a esas (y muchas similares ) preguntas, mientras que cuando uso por ej. Sass y Handlebars, entonces tengo que conocer tres conjuntos de esas respuestas y comprender sus implicaciones.

No quiere decir que de una forma u otra siempre es mejor, pero cada vez que introduce otro idioma en la mezcla, paga un precio que puede no ser tan obvio a primera vista, y este precio es complejo.

Espero haber aclarado un poco lo que quise decir originalmente.

El enlace de datos

Enlace bidireccional

Este es un tema realmente interesante y, de hecho, también es una cuestión de preferencia. Dos vías no siempre es mejor que una. Se trata de cómo desea modelar el estado mutable en su aplicación. Siempre vi los enlaces bidireccionales como una idea algo contraria a los principios de la programación funcional, pero la programación funcional no es el único paradigma que funciona, algunas personas prefieren este tipo de comportamiento y ambos enfoques parecen funcionar bastante bien en la práctica. Si está interesado en los detalles de las decisiones de diseño relacionadas con el modelado del estado en React, mire la charla de Pete Hunt (vinculada a la pregunta) y la charla de Tom Occhino y Jordan Walke,  quienes lo explican muy bien en mi opinión.

Actualización: Vea también otra charla de Pete Hunt: Sea predecible, no correcto: programación DOM funcional .

Actualización 2: Vale la pena señalar que muchos desarrolladores argumentan en contra del flujo de datos bidireccional, o el enlace bidireccional, algunos incluso lo llaman antipatrón. Tomemos por ejemplo el flujo arquitectura de la aplicación que evita explícitamente la MVC modelo (que resultó ser difícil de escalar para aplicaciones de gran Facebook e Instagram) a favor de un flujo de datos estrictamente unidireccional (ver el Camino Hacker: Rethinking Web desarrollo de aplicaciones en Facebook hablar por Tom Occhino, Jing Chen y Pete Hunt para una buena introducción). Además, muchas críticas contra AngularJS (el marco web más popular que se basa libremente en el modelo MVC, conocido por el enlace de datos bidireccional) incluye argumentos en contra de ese flujo de datos bidireccional, consulte:

Actualización 3: Otro artículo interesante que explica muy bien algunos de los problemas discutidos anteriormente es Deconstruir Flux de ReactJS: no usar MVC con ReactJS por Mikael Brassman, autor de RefluxJS (una biblioteca simple para la arquitectura de aplicación de flujo de datos unidireccional inspirada en Flux).

Actualización 4: Ember.js actualmente se está alejando del enlace de datos bidireccional y en versiones futuras será unidireccional por defecto. Ver: El futuro de Ember, charla de Stefan Penner del Simposio Embergarten en Toronto el 15 de noviembre de 2014.

Actualización 5: Vea también: The Road to Ember 2.0 RFC - discusión interesante en la solicitud de extracción de Tom Dale :

"Cuando diseñamos la capa de plantillas original, supusimos que hacer todos los enlaces de datos en dos direcciones no era muy dañino: si no establece un enlace en dos direcciones, ¡es un enlace en una sola dirección!

Desde entonces nos hemos dado cuenta (con la ayuda de nuestros amigos de React), que los componentes quieren poder entregar datos a sus hijos sin tener que estar en guardia para las mutaciones rebeldes.

Además, la comunicación entre componentes a menudo se expresa más naturalmente como eventos o devoluciones de llamada . Esto es posible en Ember, pero el dominio de los enlaces de datos bidireccionales a menudo lleva a las personas por el camino del uso de enlaces bidireccionales como canal de comunicación . Los desarrolladores experimentados de Ember no (generalmente) cometen este error, pero es fácil de cometer ". [Énfasis agregado]

Nativo vs. VM

Soporte de navegador nativo (lea "garantizado para ser más rápido")

Ahora, finalmente, algo que no es una cuestión de opinión.

En realidad, aquí es exactamente al revés. Por supuesto, el código "nativo" se puede escribir en C ++, pero ¿en qué cree que están escritos los motores de JavaScript?

De hecho, los motores de JavaScript son realmente sorprendentes en las optimizaciones que usan hoy en día, y no solo V8, sino también SpiderMonkey e incluso Chakra brilla en estos días. Y tenga en cuenta que con los compiladores JIT, el código no solo es tan nativo como puede ser, sino que también hay oportunidades de optimización del tiempo de ejecución que son simplemente imposibles de hacer en cualquier código compilado estáticamente.

Cuando las personas piensan que JavaScript es lento, generalmente se refieren a JavaScript que accede al DOM. El DOM es lento. Es nativo, escrito en C ++ y, sin embargo, es lento como el infierno debido a la complejidad que tiene que implementar.

Abre tu consola y escribe:

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

y vea cuántas propiedades divdebe implementar un elemento vacío que ni siquiera está conectado al DOM. Estas son solo las  propiedades de primer nivel que son "propiedades propias", es decir. no heredado de la cadena prototipo:

alinear, en espera, en cambio de volumen, en actualización de tiempo, en suspensión, en presentación, en instalación, en demostración, en selección, en búsqueda, en buscado, en exploración, en tamaño, en reposo, en tasa de cambio, en progreso, en reproducción, en reproducción, en pausa, en rueda de ratón, en ratón, en ratón, en el ratón, en el ratón, en el ratón, en el ratón, en el ratón, en el ratón, en el ratón, en el ratón, en el ratón onmouseenter, onmousedown, onloadstart, onloadedmetadata, onloadeddata, onload, onkeyup, onkeypress, onkeydown, oninvalid, oninput, onfocus, onerror, onended, onemptied, ondurationchange, ondrop, ondragstart, ondragover, ondragleave, ondrage, ondrage, ondrage, ondrage, ondrage. oncontextmenu, onclose, onclick, onchange, oncanplaythrough, oncanplay, oncancel, onblur, onabort, spellcheck, isContentEditable, contentEditable, outsideText, innerText, accessKey, hidden, webkitdropzone, draggable, tabIndex, dir, translate, lang, title, childElementCoofirstElementChild, children, nextElementSibling, anteriorElementSibling, onwheel, onwebkitfullscreenerror, onwebkitfullscreenchange, onselectstart, onsearch, onpaste, oncut, oncopy, onbeforepaste, onbeforepaste,. clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offsetTop, offsetLeft, localName, prefix, namespaceURI, id, style, atributos, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, firstChild, firstChild, firstChild, firstChild, firstChild, firstChild parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, conjunto de datos, classList, className, externalHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offset, offset, namespaceURI, id, estilo, atributos, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, conjunto de datos, classList, className, externalHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offset, offset, namespaceURI, id, estilo, atributos, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameparentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameparentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeName

Muchos de ellos son en realidad objetos anidados: para ver las propiedades de segundo nivel (propias) de un nativo vacío diven su navegador, consulte este violín .

Quiero decir en serio, ¿ propiedad onvolumechange en cada nodo div? ¿Es un error? No, es solo una versión de modelo de evento tradicional DOM Nivel 0 heredado de uno de los controladores de eventos "que deben ser compatibles con todos los elementos HTML , como atributos de contenido y atributos IDL" [énfasis agregado] en la Sección 6.1.6.2 de la especificación HTML por W3C - no hay forma de evitarlo.

Mientras tanto, estas son las propiedades de primer nivel de un falso DOM diven React:

accesorios, _owner, _lifeCycleState, _pendingProps, _pendingCallbacks, _pendingOwner

Toda una diferencia, ¿no? De hecho, este es el objeto completo serializado a JSON ( DEMO EN VIVO ), porque bueno, en realidad puedes  serializarlo a JSON ya que no contiene referencias circulares, algo impensable en el mundo del DOM nativo ( donde solo arrojaría una excepción ):

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

Esta es la razón principal por la que React puede ser más rápido que el DOM nativo del navegador, ya que no tiene que implementar este desastre .

Vea esta presentación de Steven Luscher para ver qué es más rápido: DOM nativo escrito en C ++ o un DOM falso escrito completamente en JavaScript. Es una presentación muy justa y entretenida.

Actualización: Ember.js en futuras versiones utilizará un DOM virtual fuertemente inspirado por React para mejorar el rendimiento. Ver: El futuro de Ember, charla de Stefan Penner del Simposio Embergarten en Toronto el 15 de noviembre de 2014.

En resumen: las características de los componentes web como plantillas, enlace de datos o elementos personalizados tendrán muchas ventajas sobre React, pero hasta que el modelo de objeto del documento se simplifique significativamente, el rendimiento no será una de ellas.

Actualizar

Dos meses después de que publiqué estas respuestas, hubo algunas noticias relevantes aquí. Como acabo de escribir en Twitter , la última versión del editor de texto Atom escrito por GitHub en JavaScript utiliza React de Facebook para obtener un mejor rendimiento, aunque según Wikipedia "Atom se basa en Chromium y está escrito en C ++", por lo que tiene control total de la implementación nativa de C ++ DOM (ver The Nucleus of Atom ) y está garantizado para tener soporte para componentes web, ya que se envía con su propio navegador web. Es solo un ejemplo muy reciente de un proyecto del mundo real que podría haber utilizado cualquier otro tipo de optimización que normalmente no está disponible para aplicaciones web y, sin embargo, ha elegido utilizar React, que está escrito en JavaScript, para lograr el mejor rendimiento, aunque Atom para empezar no se creó con React, por lo que hacerlo no fue un cambio trivial.

Actualización 2

Hay una comparación interesante de Todd Parker usando WebPagetest para comparar el rendimiento de los ejemplos de TodoMVC escritos en Angular, Backbone, Ember, Polymer, CanJS, YUI, Knockout, React y Shoestring. Esta es la comparación más objetiva que he visto hasta ahora. Lo significativo aquí es que todos los ejemplos respectivos fueron escritos por expertos en todos esos marcos, todos están disponibles en GitHub y pueden ser mejorados por cualquiera que piense que parte del código podría optimizarse para ejecutarse más rápido.

Actualización 3

Ember.js en futuras versiones incluirá una serie de características de React que se analizan aquí (incluido un DOM virtual y enlace de datos unidireccional, por nombrar solo algunas), lo que significa que las ideas que se originaron en React ya están migrando a otros marcos. Ver: The Road to Ember 2.0 RFC: discusión interesante en la solicitud de extracción de Tom Dale (Fecha de inicio: 03/12/2014): "En Ember 2.0, adoptaremos un" DOM ​​virtual "y un modelo de flujo de datos que abarque el mejores ideas de React y simplifica la comunicación entre componentes ".

Además, Angular.js 2.0 está implementando muchos de los conceptos discutidos aquí.

Actualización 4

Tengo que elaborar algunos temas para responder a este comentario de Igwe Kalu:

"no es sensato comparar React (JSX o el resultado de la compilación) con JavaScript simple, cuando React finalmente se reduce a JavaScript simple. [...] Cualquier estrategia que React use para la inserción DOM puede aplicarse sin usar React. Dicho esto, no agrega ningún beneficio especial al considerar la característica en cuestión que no sea la conveniencia ". (comentario completo aquí )

En caso de que no fuera lo suficientemente claro, en parte de mi respuesta, estoy comparando el rendimiento de operar directamente en el DOM nativo (implementado como objetos host en el navegador) versus el DOM falso / virtual de React (implementado en JavaScript). El punto que estaba tratando de hacer es que el DOM virtual implementado en JavaScript puede superar el DOM real implementado en C ++ y no que React puede superar a JavaScript (lo que obviamente no tendría mucho sentido ya que está escrito en JavaScript). Mi punto era que no siempre se garantiza que el código "nativo" de C ++ sea más rápido que el JavaScript "no nativo". Usar React para ilustrar ese punto fue solo un ejemplo.

Pero este comentario tocó un tema interesante. En cierto sentido, es cierto que no necesita ningún marco (React, Angular o jQuery) por ningún motivo (como el rendimiento, la portabilidad, las características) porque siempre puede recrear lo que el marco hace por usted y reinventar la rueda, si puede justificar el costo, eso es.

Pero, como bien dijo Dave Smith en Cómo perder el punto al comparar el rendimiento del marco web : "Al comparar dos marcos web, la pregunta no es si mi aplicación puede ser rápida con el marco X. La pregunta es si mi aplicación será rápida con el marco X."

En mi respuesta de 2011 a: ¿Cuáles son algunas razones técnicas empíricas para no usar jQuery ? Explico un problema similar, que no es imposible escribir código portátil de manipulación de DOM sin una biblioteca como jQuery, pero que la gente rara vez lo hace.

Cuando se usan lenguajes de programación, bibliotecas o marcos, las personas tienden a usar las formas más convenientes o idiomáticas de hacer las cosas, no las perfectas sino las inconvenientes. El verdadero valor de los buenos marcos es facilitar lo que de otro modo sería difícil de hacer, y el secreto es hacer que las cosas correctas sean convenientes. El resultado sigue teniendo exactamente el mismo poder a su disposición que la forma más simple de cálculo lambda o la máquina de Turing más primitiva, pero la relativa expresividad de ciertos conceptos significa que esos mismos conceptos tienden a expresarse más fácilmente o en absoluto, y eso Las soluciones correctas no solo son posibles sino que se implementan ampliamente.

Actualización 5

Reaccionar + Rendimiento =? El artículo de Paul Lewis de julio de 2015 muestra un ejemplo en el que React es más lento que JavaScript de vainilla escrito a mano para obtener una lista infinita de imágenes de Flickr, lo que es especialmente significativo en dispositivos móviles. Este ejemplo muestra que todos deben probar siempre el rendimiento para casos de uso específicos y plataformas y dispositivos de destino específicos.

Gracias a Kevin Lozandier por llamar mi atención .

rsp
fuente
75
eso es lo que yo llamo una respuesta integral, ¡gracias!
Demwunz
14
Parece que Atom se está alejando de React. Ver github.com/atom/atom/issues/3677 .
Juho Vepsäläinen
66
@ash: si lees más abajo en el hilo, hablan sobre cómo les gustaría eventualmente alejarse por completo de React y otros marcos, y simplemente rodar los suyos usando elementos personalizados y el DOM de sombra.
musicfreak
3
Solo para aclarar la redacción anterior, en la lista de @ErikAllik, FRP (Functional Reactive Programming) no es un lenguaje nuevo sino un enfoque que está ganando popularidad. De hecho, "Elm se basa en la idea de la Programación Reactiva Funcional" (de elm-lang.org), y como él mencionó, existen marcos FRP para Haskell, etc.
Jon Coombs
55
tl; leer de todos modos - ¡respuesta brillante y detallada!
Mark K Cowan
16

El polímero es asombroso. Reaccionar es asombroso. No són la misma cosa.

Polymer es una biblioteca para construir componentes web compatibles con versiones anteriores.

Reaccionar es la V en MVC. Es la vista, y nada más. No por sí mismo al menos.

Reaccionar no es un marco.

React + Flux + Node + (Gulp o Grunt) es más comparable a un marco, pero 3 de esas cosas no son parte de reaccionar en absoluto.

Hay muchas tecnologías, patrones y estilos arquitectónicos que los desarrolladores reaccionan, pero reaccionar en sí mismo no es un marco.

Es triste que nadie se haya tomado el tiempo para decir lo más simple posible, que no se los pueda comparar. Tienen cierta superposición, pero son más diferentes que lo mismo.

Ambos le permiten definir componentes web, pero de diferentes maneras. Más allá de eso, son herramientas muy, muy diferentes.

Robotsushi
fuente
¿No es React tanto el M como el V, no solo el V, ya que contiene y actualiza el estado de los datos y renderiza fragmentos de html a través de componentes?
abelito
1
Hay bibliotecas de gestión de estado de reacción como flux o redux, pero estas no están empaquetadas con react.
Robotsushi
Ah, ya veo, no consideramos que los datos de Vista sean datos del modelo ... hasta que se envíen al lado del servidor. A pesar de que React contiene el estado del componente (ver datos), sigue siendo ver datos hasta el envío. Eso tiene sentido.
abelito
15

Los chicos de React tienen una muy buena explicación sobre la comparación entre React y Web Components:

Intentar comparar y contrastar Reaccionar con WebComponents inevitablemente resulta en conclusiones engañosas, porque las dos bibliotecas están construidas para resolver diferentes problemas. WebComponents proporciona una fuerte encapsulación para componentes reutilizables, mientras que React proporciona una biblioteca declarativa que mantiene el DOM sincronizado con sus datos. Los dos objetivos son complementarios; Los ingenieros pueden mezclar y combinar las tecnologías. Como desarrollador, puede usar React en sus WebComponents, o WebComponents en React, o ambos.

Erik Allik
fuente
14

Otra respuesta en un punto específicamente:

Escriba JavaScript en JavaScript vainilla, escriba CSS en CSS, escriba HTML en HTML.

Nada le impide escribir Javascript en, por ejemplo, CoffeeScript, TypeScript, ClojureScript o cualquier otra cosa. Es puramente una cuestión de preferencia.

HTML es el mejor DSL para documentos HTML estáticos . Pero no proporciona nada para HTML dinámico. Y en el navegador, el mejor lenguaje para hacer que HTML sea dinámico es Javascript, no HTML puro con manipulación DOM ad-hoc de JavaScript o lenguaje de plantilla como Manillares que ni siquiera son medios idiomas.

Para CSS, si su CSS es estático, lo escribe como de costumbre. Si necesita ser dinámico en función de algunos valores de tiempo de ejecución, es la misma historia que HTML: Javascript es la mejor manera de hacerlo dinámico.

DjebbZ
fuente
1
Aprecio la respuesta, pero ese no era realmente mi punto. ¿Espero que mis ediciones aclaren un poco la pregunta?
CletusW
1
Lo siento, no lo hace. Todavía puede escribir su estilo en cualquier idioma de estilos en un archivo separado. Y JSX de React hace que parezca que estás usando un lenguaje de marcado.
DjebbZ
3
"Javascript es la mejor manera de hacer que [CSS] sea dinámico", simplemente diciendo que en realidad no explica por qué.
pilau
1
Bueno, si los estilos / clases necesitan cambiar de acuerdo con la entrada del usuario o las reglas comerciales, simplemente use JavaScript para cambiarlos. En vanilla js, manipularía las propiedades classList o styles de un nodo DOM. Con React puedes lograr el mismo objetivo manipulando el DOM virtual. ¿Está más claro?
DjebbZ
2
Vjeux, colaborador principal de React, recientemente dio una charla donde impulsa el concepto "CSS en JS" usando React. Creo que es interesante, puede estar dispuesto a ver de qué se trata: blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html
DjebbZ
6

No he usado componentes web, pero parece que requieren que agregue lógica de mutación codificada manualmente a los controladores de eventos.

fragmento del ejemplo de Polymer:

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

El objetivo de React es reducir la complejidad eliminando la lógica de mutación. En cambio, ingenuamente regeneras un DOM virtual y dejas que el algoritmo diff de React descubra qué necesita cambiar en el DOM real.

limscoder
fuente
55
No estoy seguro de dónde obtuviste ese ejemplo, pero Polymer también desalienta la mutación DOM manual a favor del enlace de datos, incluso para los nombres de clase .
CletusW
Es el ejemplo de la pestaña "crear elementos" en la página principal de polímero -proyecto.org.
limscoder
44
Wow, tienes razón! Supongo que solo querían un ejemplo de búsqueda automática de nodos. Sin embargo, probablemente no sea el mejor para dar.
CletusW
6

Creo que el mayor inconveniente de React en mi opinión es que no está basado en estándares web. React es una herramienta muy poderosa en este momento, pero debido a que evita mucho de lo que proporciona el navegador siempre que sea posible, las decisiones que parecían tener sentido ahora probablemente no tendrán sentido en unos pocos años a medida que las instalaciones integradas de los navegadores continúen funcionando. mejorar. Así que me gustaría hablar sobre eso y cómo afecta algunos aspectos diferentes de las aplicaciones web.

Actuación

A la gente le gusta argumentar que la ventaja de React es que reinventa por completo todo el DOM y el modelo de eventos, y que el DOM estándar existente es pesado y costoso, pero al final del día no he encontrado el rendimiento de Reaccione para ser mejor de lo que puedo obtener de una aplicación Backbone o Polymer bien escrita. De hecho, en la mayor parte de mi experiencia profesional, el rendimiento de React en realidad ha sido un poco peor. Eso no quiere decir que React sea lento ... Simplemente no es la elección de rendimiento de vanguardia que todos pensamos que era antes de tenerlo en nuestras manos.

En la respuesta de rsp, señala que el modelo DOM de React para un div es mucho más liviano que el div DOM nativo, y eso es ciertamente cierto. Sin embargo, para que React sea útil, ese div 'virtual' tiene que terminar convirtiéndose en un div real en algún momento. Entonces, en mi visión del mundo, no se trata de un div React frente a un div nativo. Es un div React + un div nativo vs solo un div nativo. La sobrecarga de la versión de React del DOM no es trivial, y si los estándares alguna vez eliminan algunos de esos atributos innecesarios y permiten que los nodos DOM nativos sean mucho más ligeros, de repente esa sobrecarga parecerá realmente costosa.

En uno de mis lugares de empleo anteriores, tuvimos algunas aplicaciones en Polymer y algunas aplicaciones en React. Una de las primeras aplicaciones de Polymer terminó siendo reescrita en React porque eso era lo que la compañía tenía estándar, y en base a las mediciones que tomé, la versión React de esta misma aplicación terminó usando aproximadamente un 30% más de memoria que la versión Polymer , y aunque la diferencia fue marginal, la versión Polymer también se renderizó en menos tiempo. Una cosa a considerar aquí es que estamos hablando de aplicaciones escritas por personas, y las personas no son perfectas, por lo que podría ser posible que la implementación de React de esta aplicación no se aprovechara de todo lo que React es capaz de hacer. Pero creo que al menos algo tiene que ver con la sobrecarga en la que React incurre al tener su propia versión del DOM.

React reinventa todo el DOM usando su propio modelo y luego lo usa para una optimización de rendimiento importante. Una vista se representa en un DOM virtual, y eso se proyecta en el DOM real. Cuando hay un cambio y la vista debe actualizarse, la vista se vuelve a representar nuevamente en un DOM virtual nuevamente, y ese árbol se diferencia contra el árbol anterior para determinar qué nodos se deben cambiar en el DOM real para reflejar este cambio en la vista Si bien este es un enfoque muy inteligente para realizar actualizaciones de DOM eficientes, existe la sobrecarga de mantener todos estos árboles de DOM virtuales y diferenciarlos para determinar qué cambiar en el DOM real. En este momento, esta sobrecarga se ve compensada en gran medida por los beneficios de rendimiento, pero a medida que el DOM nativo mejora con el tiempo, la escala cambiará en la otra dirección. Me preocupa cómo podrían envejecer las aplicaciones React, y si dentro de 3 años serán mucho más lentos que las cosas que tratan con el DOM más directamente. Este enfoque de DOM virtual es un poco complicado, y otras bibliotecas como Polymer han podido implementar enfoques muy eficientes para tratar el DOM de una manera mucho más sutil.

Actualización para el rendimiento: una de las bibliotecas con las que me he tropezado hace un tiempo hace lo que creo que es un mejor trabajo para administrar las actualizaciones del DOM. Es la biblioteca Dom incremental de Google, y creo que el hecho de que funciona con el dom en el lugar y no tiene que crear una 'copia virtual' es un enfoque mucho más limpio, con mucha menos sobrecarga de memoria. Ver más aquí: http://google.github.io/incremental-dom/#about

Componentes declarativos vs imperativos

Una de las cosas que siempre escucha cuando habla de componer componentes de su aplicación es todos los beneficios de que sus componentes sean declarativos. Dentro de la cosmovisión de React, todo es agradable y declarativo. Escribes JavaScript que devuelve marcado y React lo pega todo por ti. Y eso es genial si se trata de una nueva aplicación que solo usa React y nada más. Puede escribir algún componente y siempre que esté dentro de una pieza del DOM propiedad de React, es tan simple como poner esa etiqueta en la página para consumir su componente.

Pero tan pronto como tomas esos componentes y los usas fuera de React, las cosas se ponen mucho más complicadas. Debido a que la forma en que los componentes React se convierten en etiquetas está completamente fuera de lo que proporcionan los estándares web, nada más que React sabe cómo darle una forma declarativa de consumir estos componentes. Si quiero poner los componentes React en una vista Backbone existente que usa plantillas de manillares, debe representar un div ficticio en su plantilla con una clase o ID que pueda usar como identificador, luego escribir JavaScript imperativo para encontrar ese div dummy y montar tu componente en él. ¿Tienes una aplicación Express.js que usa plantillas del lado del servidor? Bueno, es esa misma canción y baile. ¿Una página JSP? Te ríes, pero todavía hay muchas aplicaciones que las usan. A menos que sea una especie de startup sin código existente, usted ' tendremos que escribir algunas tuberías para reutilizar sus componentes React en muchas aplicaciones. Mientras tanto, Polymer logra componentes a través del estándar de Componentes Web, y al usar la especificación de Elemento Personalizado, Polymer puede crear componentes que el navegador sabe de forma nativa cómo consumir. Puedo poner un componente Polymer en una página JSP, una plantilla Express.js, una vista ASP.NET, una vista Backbone ... incluso dentro de un componente React. Literalmente, en cualquier lugar donde pueda usar HTML, puede consumir un componente Polymer. Las personas que están diseñando para la reutilización están buscando estándares web, porque los estándares son el contrato que facilita la compatibilidad entre ellos. YouTube sigue creando más y más cosas en Polymer (fuente: Polymer logra componentes a través del estándar Web Components, y al usar la especificación de Elemento personalizado, Polymer puede crear componentes que el navegador sabe de forma nativa cómo consumir. Puedo poner un componente Polymer en una página JSP, una plantilla Express.js, una vista ASP.NET, una vista Backbone ... incluso dentro de un componente React. Literalmente, en cualquier lugar donde pueda usar HTML, puede consumir un componente Polymer. Las personas que están diseñando para la reutilización están buscando estándares web, porque los estándares son el contrato que facilita la compatibilidad entre ellos. YouTube sigue creando más y más cosas en Polymer (fuente: Polymer logra componentes a través del estándar Web Components, y al usar la especificación de Elemento personalizado, Polymer puede crear componentes que el navegador sabe de forma nativa cómo consumir. Puedo poner un componente Polymer en una página JSP, una plantilla Express.js, una vista ASP.NET, una vista Backbone ... incluso dentro de un componente React. Literalmente, en cualquier lugar donde pueda usar HTML, puede consumir un componente Polymer. Las personas que están diseñando para la reutilización están buscando estándares web, porque los estándares son el contrato que facilita la compatibilidad entre ellos. YouTube sigue creando más y más cosas en Polymer (fuente: Puedo poner un componente Polymer en una página JSP, una plantilla Express.js, una vista ASP.NET, una vista Backbone ... incluso dentro de un componente React. Literalmente, en cualquier lugar donde pueda usar HTML, puede consumir un componente Polymer. Las personas que están diseñando para la reutilización están buscando estándares web, porque los estándares son el contrato que facilita la compatibilidad entre ellos. YouTube sigue creando más y más cosas en Polymer (fuente: Puedo poner un componente Polymer en una página JSP, una plantilla Express.js, una vista ASP.NET, una vista Backbone ... incluso dentro de un componente React. Literalmente, en cualquier lugar donde pueda usar HTML, puede consumir un componente Polymer. Las personas que están diseñando para la reutilización están buscando estándares web, porque los estándares son el contrato que facilita la compatibilidad entre ellos. YouTube sigue creando más y más cosas en Polymer (fuente:http://react-etc.net/entry/youtube-is-being-rebuilt-on-web-components-and-polymer ), y solo puedo imaginar que el aspecto basado en estándares de Polymer es la razón. Ese reproductor de YouTube en el medio de la página de YouTube podría convertirse en un componente que incluya una fuente de contenido como una propiedad, y de repente cualquier persona que quiera insertar el reproductor de YouTube en su página puede usar literalmente el mismo código de reproductor que YouTube está usando. , y pueden hacerlo simplemente pegando una etiqueta en su página.

Resumen

Puedo ver que definitivamente hay algunos aspectos atractivos de React en este momento. Si todo lo que está usando es React, puede construir algunos widgets y algunos componentes y reutilizarlos declarativamente por todas partes. Pero creo que React hubiera estado mucho mejor si hubiera utilizado algunos de los estándares de Web Components para lograr lo que hace, en lugar de salir y construir un navegador dentro de un navegador y un mecanismo complejo para mantener todo sincronizado.

Perros
fuente