Pro e contro di React vs. Web Components (Polymer) di Facebook


521

Quali sono i principali vantaggi di React di Facebook rispetto alle imminenti specifiche di Web Components e viceversa (o forse un confronto più mele-a-mele sarebbe con la libreria Polymer di Google )?

Secondo questo discorso di JSConf EU e la homepage di React, i principali vantaggi di React sono:

  • Disaccoppiamento e maggiore coesione utilizzando un modello di componente
  • Astrazione, composizione ed espressività
  • DOM virtuale ed eventi sintetici (il che significa sostanzialmente che hanno completamente implementato nuovamente il DOM e il suo sistema di eventi)
    • Abilita contenuti di eventi HTML5 moderni su IE 8
    • Rendering lato server
    • testabilità
    • Associazioni a SVG, VML e <canvas>

Quasi tutto ciò che viene menzionato viene integrato nei browser in modo nativo tramite Web Components tranne questo concetto DOM virtuale (ovviamente). Posso vedere come il DOM virtuale e gli eventi sintetici possano essere utili oggi per supportare i vecchi browser, ma non sta buttando via un grosso pezzo di codice nativo del browser come spararsi nel piede a lungo termine? Per quanto riguarda i browser moderni, non è un sacco di inutili overhead / reinventare la ruota?

Qui ci sono alcune cose che penso Reagire manca che Web Components si prenderà cura di per voi. Correggimi se sbaglio.

  • Supporto browser nativo (leggi "garantito per essere più veloce")
  • Scrivi script in un linguaggio di scripting, scrivi stili in un linguaggio di stile, scrivi markup in un linguaggio di markup.
  • Incapsulamento di stili mediante Shadow DOM
    • React invece ha questo , che richiede la scrittura di CSS in JavaScript. Non carino.
  • Rilegatura a due vie

12
WRT. rilegatura a due vie. Questa funzionalità è problematica su vasta scala. In casi banali funziona bene, ma nei casi del mondo reale in genere si scopre che per mantenere il codice gestibile è necessario un viewmodel da associare, invece di associare al modello reale, il che rende quindi l'associazione bidirezionale molto meno utile di inizialmente sembrava. Penso che potrebbe essere un vantaggio di React il fatto che non fornisca un'associazione bidirezionale perché forza un'architettura adeguata del flusso di dati.
Joeri Sebrechts,

8
Ho visto React, Angular e Knockout. Trovo Knockout il più "pulito" in termini di separazione di template, dati e associazione. Volevo amare reagire, ma provando a creare un semplice Combobox, mi rendo conto che stavo scrivendo molto più codice e mescolando la logica di rendering con il modello HTML ... molto più di quanto avrei fatto usando qualcosa come HTML / jina2. Mi sembra che queste librerie / api ci stiano spostando all'indietro, non in avanti. La cosa migliore di React è la manipolazione del dom virtuale, ma posso vedere che arrivare ad altri framework stabiliti prima o poi.
mike01010,

41
Sono molto sorpreso (e anche contento!) Che questa domanda non sia stata chiusa come "principalmente basata sull'opinione".
iconoclasta il

4
Non è possibile scrivere "script in un linguaggio di scripting" e "markup in un linguaggio di markup" se si sta eseguendo modelli di qualsiasi tipo. Angolare, polimerico, ecc. Utilizzano un modello DSL incorporato in HTML. React utilizza un modello DSL incorporato in JS (JSX). Il problema con l'incorporamento di una DSL in HTML è come stabilire l'ambito per ottenere valori da JS. Questo porta al complesso sistema $ scope di Angular. In JSX, invece, l'ambito delle variabili nei template è solo l'ambito JS: lo trovo molto meno confuso.
Andy,

3
Al momento i componenti di React (se non scritti male) sarebbero più veloci degli stessi in qualsiasi framework DOM. La magia v-dom e diffing è l'USP di reagire. Il mio punto è: perché i browser non dovrebbero creare una differenza come quella nel loro set nativo. Ciò che li ferma, e se nulla (li ferma), allora il piombo di React probabilmente avrà vita breve.
fasttrainofthoughts

Risposte:


664

Aggiornamento:  questa risposta sembra essere piuttosto popolare, quindi ho impiegato un po 'di tempo per ripulirla un po', aggiungere alcune nuove informazioni e chiarire alcune cose che pensavo non fossero abbastanza chiare. Per favore, commenta se pensi che qualcos'altro abbia bisogno di chiarimenti o aggiornamenti.

La maggior parte delle tue preoccupazioni sono in realtà una questione di opinioni e preferenze personali, ma cercherò di rispondere nel modo più obiettivo possibile:

Nativo vs. Compilato

Scrivi JavaScript in vanilla JavaScript, scrivi CSS in CSS, scrivi HTML in HTML.

In passato ci sono stati dibattiti caldi sulla possibilità di scrivere  manualmente l'Assemblea nativa o utilizzare un linguaggio di livello superiore come C per fare in modo che il compilatore generi il codice dell'Assemblea per te. Ancor prima che la gente si rifiutasse di fidarsi degli assemblatori e preferiva scrivere a mano il codice macchina nativo ( e non sto scherzando ).

Nel frattempo, oggi ci sono molte persone che scrivono HTML in Haml o Jade , CSS in Sass o Less e JavaScript in CoffeeScript o TypeScript . È lì. Funziona. Alcune persone lo preferiscono, altri no.

Il punto è che non c'è nulla di fondamentalmente sbagliato nel non scrivere JavaScript in JavaScript vaniglia, CSS in CSS e HTML in HTML. È davvero una questione di preferenza.

DSL interni vs. esterni

 L'incapsulamento di stile con Shadow DOM React ha invece questo, che richiede la scrittura di CSS in JavaScript. Non carino.

Abbastanza o no, è certamente espressivo. JavaScript è un linguaggio molto potente, molto più potente dei CSS (incluso anche uno qualsiasi dei preprocessori CSS). Dipende dal fatto che tu preferisca DSL interne o esterne per questo genere di cose. Ancora una volta, una questione di preferenza.

(Nota: stavo parlando degli stili inline in React a cui faceva riferimento la domanda originale.)

Tipi di DSL - spiegazione

Aggiornamento: leggendo la mia risposta qualche tempo dopo averla scritta, penso di dover spiegare cosa intendo qui. DSL è un linguaggio specifico del dominio e può essere interno (usando la sintassi della lingua host come JavaScript - come ad esempio React senza JSX, o come gli stili inline in React menzionati sopra) o può essere esterno (usando una sintassi diversa rispetto alla lingua host, come in questo esempio sarebbe incorporare CSS (un DSL esterno) all'interno di JavaScript).

Può essere fonte di confusione perché alcune pubblicazioni usano termini diversi rispetto a "interno" ed "esterno" per descrivere quel tipo di DSL. A volte viene utilizzato "incorporato" anziché "interno" ma la parola "incorporato" può significare cose diverse, ad esempio Lua è descritta come "Lua: un linguaggio incorporato estensibile" in cui incorporato non ha nulla a che fare con il DSL incorporato (interno) (in il che significa che è esattamente l'opposto - un DSL esterno) ma significa che è incorporato nello stesso senso che, ad esempio, SQLite è un database incorporato. Esiste anche eLua in cui "e" sta per "incorporato" in un terzo senso - che è pensato per sistemi embedded! Ecco perché non mi piace usare il termine "DSL incorporato" perché cose come eLua possono essere "DSL" che sono "incorporate" in due sensi diversi pur non essendo affatto un "DSL incorporato"!

A peggiorare le cose alcuni progetti introducono ancora più confusione nel mix. Per esempio. I modelli flatiron sono descritti come "privi di DSL" mentre in realtà è solo un perfetto esempio di DSL interno con sintassi come:map.where('href').is('/').insert('newurl');

Detto questo, quando ho scritto "JavaScript è un linguaggio molto potente, molto più potente del CSS (incluso anche uno qualsiasi dei preprocessori CSS). Dipende dal fatto che tu preferisca DSL interne o esterne per questo genere di cose. Ancora una volta, una questione di preferenza ". Stavo parlando di quei due scenari:

Uno:

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

Due:

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

Il primo esempio usa ciò che è stato descritto nella domanda come: "scrivere CSS in JavaScript. Non carino." Il secondo esempio usa Sass. Mentre sono d'accordo che l'uso di JavaScript per scrivere CSS potrebbe non essere carino (per alcune definizioni di "grazioso"), ma c'è un vantaggio nel farlo.

Posso avere variabili e funzioni in Sass ma sono con ambito lessicale o dinamico? Sono digitati staticamente o dinamicamente? Fortemente o debolmente? E i tipi numerici? Digitare la coerizione? Quali valori sono veri e quali sono falsi? Posso avere funzioni di ordine superiore? Ricorsione? La coda chiama? Chiusure lessicali? Sono valutati in ordine normale o in ordine applicativo? C'è una valutazione pigra o desiderosa? Gli argomenti alle funzioni vengono passati per valore o per riferimento? Sono mutabili? Immutabile? Persistente? E gli oggetti? Classi? Prototipi? Eredità?

Quelle non sono domande banali eppure devo conoscere le risposte se voglio capire il codice Sass o Less. Conosco già quelle risposte per JavaScript, quindi significa che capisco già ogni DSL interno (come gli stili inline in React) su quegli stessi livelli, quindi se uso React allora devo conoscere solo una serie di risposte a quelle (e molte simili ) domande, mentre quando uso ad es. Sass e Manubrio quindi devo conoscere tre serie di quelle risposte e capire le loro implicazioni.

Non vuol dire che in un modo o nell'altro sia sempre meglio, ma ogni volta che si introduce un'altra lingua nel mix, si paga un prezzo che potrebbe non essere così ovvio a prima vista, e questo prezzo è complessità.

Spero di aver chiarito un po 'cosa intendevo inizialmente.

Associazione dati

Rilegatura a due vie

Questo è un argomento davvero interessante e in effetti anche una questione di preferenza. Il doppio senso non è sempre meglio del solo senso. È una domanda su come si desidera modellare lo stato mutabile nella propria applicazione. Ho sempre considerato le associazioni bidirezionali un'idea piuttosto contraria ai principi della programmazione funzionale, ma la programmazione funzionale non è l'unico paradigma che funziona, alcune persone preferiscono questo tipo di comportamento ed entrambi gli approcci sembrano funzionare abbastanza bene nella pratica. Se sei interessato ai dettagli delle decisioni di progettazione relative alla modellistica dello stato in React, guarda il discorso di Pete Hunt (collegato alla domanda) e il discorso di Tom Occhino e Jordan Walke  che lo spiegano molto bene in la mia opinione.

Aggiornamento: vedi anche un altro discorso di Pete Hunt: sii prevedibile, non corretto: programmazione DOM funzionale .

Aggiornamento 2: Vale la pena notare che molti sviluppatori stanno discutendo contro il flusso di dati bidirezionale o l'associazione bidirezionale, alcuni addirittura lo definiscono un anti-pattern. Prendiamo ad esempio il Flux architettura applicativa che evita in modo esplicito il MVC modello (che si è rivelata difficile da scalare per grandi Facebook e Instagram applicazioni) a favore di un flusso di dati strettamente unidirezionale (vedere la Via Hacker: Ripensare Web App per lo sviluppo Facebook parlare da Tom Occhino, Jing Chen e Pete Hunt per una buona introduzione). Inoltre, molta critica contro AngularJS (il framework Web più popolare che è vagamente basato sul modello MVC, noto per l'associazione di dati bidirezionale) include argomenti contro quel flusso di dati bidirezionale, vedere:

Aggiornamento 3: Un altro articolo interessante che spiega bene alcuni dei problemi discussi sopra è Decostruire il flusso di ReactJS - Non usare MVC con ReactJS di Mikael Brassman, autore di RefluxJS (una semplice libreria per l'architettura applicativa unidirezionale del flusso di dati ispirata da Flux).

Aggiornamento 4: Ember.js si sta attualmente allontanando dall'associazione dati bidirezionale e nelle versioni future sarà a senso unico per impostazione predefinita. Vedi: The Future of Ember talk di Stefan Penner dell'Embergarten Symposium di Toronto il 15 novembre 2014.

Aggiornamento 5: Vedi anche: The Road to Ember 2.0 RFC - discussione interessante nella richiesta pull di Tom Dale :

"Quando abbiamo progettato il layer di template originale, abbiamo pensato che rendere tutti i binding di dati bidirezionali non fosse molto dannoso: se non si imposta un binding bidirezionale, è di fatto un binding unidirezionale!

Da allora ci siamo resi conto (con l'aiuto dei nostri amici di React) che i componenti vogliono essere in grado di distribuire dati ai propri figli senza dover essere in guardia per mutazioni ribelli.

Inoltre, la comunicazione tra i componenti è spesso espressa in modo più naturale come eventi o callback . Ciò è possibile in Ember, ma il predominio dei binding di dati bidirezionali spesso porta le persone a seguire un percorso di utilizzo dei binding bidirezionali come canale di comunicazione . Gli sviluppatori esperti di Ember non (di solito) commettono questo errore, ma è facile da fare. " [Enfasi aggiunta]

Nativo vs. VM

Supporto browser nativo (leggi "garantito per essere più veloce")

Ora finalmente qualcosa che non è una questione di opinione.

In realtà qui è esattamente il contrario. Naturalmente il codice "nativo" può essere scritto in C ++ ma in che cosa pensi siano scritti i motori JavaScript?

È un dato di fatto che i motori JavaScript sono davvero sorprendenti nelle ottimizzazioni che usano oggi - e non solo più V8, anche SpiderMonkey e persino Chakra brillano in questi giorni. E tieni presente che con i compilatori JIT il codice non è solo nativo come può essere, ma ci sono anche opportunità di ottimizzazione del tempo di esecuzione che sono semplicemente impossibili da fare in qualsiasi codice compilato staticamente.

Quando le persone pensano che JavaScript sia lento, di solito significano JavaScript che accede al DOM. Il DOM è lento. È nativo, scritto in C ++ e tuttavia è lento come l'inferno a causa della complessità che deve implementare.

Apri la tua console e scrivi:

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

e vedi quante proprietà divdeve implementare un elemento vuoto che non è nemmeno collegato al DOM. Queste sono solo le  proprietà di primo livello che sono "proprietà proprie" cioè. non ereditato dalla catena di prototipi:

allineare, in attesa, onvolumechange, ontimeupdate, onsuspend, onsubmit, onstalled, onshow, onselect, onseeking, onseeked, onscroll, onresize, onreset, onratechange, onprogress, onplaying, onplay, onpuse, onmousewheelmomo onmouseup onmouseenter, onmousedown, onloadstart, onloadedmetadata, onloadeddata, onload, onkeyup, onkeypress, onkeydown, oninvalid, oninput, onfocus, onerror, onended, onemptied, ondurationchange, ondrop, ondragstart, ondragover, ondragcend oncontextmenu, onclose, onclick, onchange, oncanplaythrough, oncanplay, oncancel, onblur, onabort, spellcheck, isContentEditable, contentEditable, outerText, innerText, accessKey, hidden, webkitdropzone, trascinabile, tabIndex, dir, translate, last, elementfirstElementChild, children, nextElementSibling, previousElementSibling, onwheel, onwebkitfullscreenerror, onwebkitfullscreenchange, onselectstart, onsearch, onpaste, oncut, oncopy, onbeforepaste, onbeforecut, scrollTermetHotetThetetHot clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offsetTop, offsetLeft, localName, prefisso, namespaceURI, id, stile, attributi, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, lastChild parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, dataset, classList, className, outerHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientTop, clientLeft, offsetPop namespaceURI, id, stile, attributi, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, dataset, classList, className, outerHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientTop, clientLeft, offsetPop namespaceURI, id, stile, attributi, 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

Molti di loro sono in realtà oggetti nidificati - per vedere le proprietà (proprie) di secondo livello di un nativo vuoto divnel tuo browser, vedi questo violino .

Intendo seriamente, proprietà onvolumechange su ogni singolo nodo div? È un errore? No, è solo una versione tradizionale del modello di eventi DOM livello 0 legacy di uno dei gestori di eventi "che deve essere supportata da tutti gli elementi HTML , in quanto sia gli attributi del contenuto che gli attributi IDL" [enfasi aggiunta] nella Sezione 6.1.6.2 delle specifiche HTML di W3C - nessun modo per aggirarlo.

Nel frattempo, queste sono le proprietà di primo livello di un falso DOM divin React:

oggetti di scena, _owner, _lifeCycleState, _pendingProps, _pendingCallbacks, _pendingOwner

Piuttosto una differenza, no? In realtà questo è l'intero oggetto serializzato per JSON ( LIVE DEMO ), perché ehi è effettivamente possibile  serializzare per JSON in quanto non contiene riferimenti circolari - qualcosa di impensabile nel mondo del DOM nativa ( dove sarebbe solo un'eccezione ):

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

Questo è praticamente il motivo principale per cui React può essere più veloce del DOM del browser nativo, perché non deve implementare questo pasticcio .

Guarda questa presentazione di Steven Luscher per vedere cosa è più veloce: DOM nativo scritto in C ++ o un DOM falso scritto interamente in JavaScript. È una presentazione molto giusta e divertente.

Aggiornamento: Ember.js nelle versioni future utilizzerà un DOM virtuale fortemente ispirato a React per migliorare le prestazioni. Vedi: The Future of Ember talk di Stefan Penner dell'Embergarten Symposium di Toronto il 15 novembre 2014.

Riassumendo: funzionalità di componenti Web come modelli, associazione di dati o elementi personalizzati avranno molti vantaggi rispetto a React ma fino a quando il modello di oggetti del documento stesso non sarà notevolmente semplificato, le prestazioni non saranno una di queste.

Aggiornare

Due mesi dopo aver pubblicato queste risposte, c'erano alcune novità rilevanti qui. Come ho appena scritto su Twitter , l'ultima versione dell'editor di testo Atom scritto da GitHub in JavaScript utilizza React di Facebook per ottenere prestazioni migliori anche se secondo Wikipedia "Atom è basato su Chromium e scritto in C ++", quindi ha il pieno controllo di l'implementazione DOM C ++ nativa (vedi The Nucleus of Atom ) e è garantito il supporto per i componenti Web poiché viene fornito con il proprio browser Web. È solo un esempio molto recente di un progetto del mondo reale che avrebbe potuto utilizzare qualsiasi altro tipo di ottimizzazione in genere non disponibile per le applicazioni Web e tuttavia ha scelto di utilizzare React che è esso stesso scritto in JavaScript, per ottenere le migliori prestazioni, anche se Atom all'inizio non è stato creato con React, quindi non è stato un cambiamento banale.

Aggiornamento 2

Esiste un interessante confronto di Todd Parker che utilizza WebPagetest per confrontare le prestazioni degli esempi di TodoMVC scritti in Angular, Backbone, Ember, Polymer, CanJS, YUI, Knockout, React e Shoestring. Questo è il confronto più oggettivo che ho visto finora. Ciò che è significativo qui è che tutti i rispettivi esempi sono stati scritti da esperti in tutti quei framework, sono tutti disponibili su GitHub e possono essere migliorati da chiunque pensi che parte del codice possa essere ottimizzato per funzionare più velocemente.

Aggiornamento 3

Ember.js nelle versioni future includerà una serie di funzionalità di React che verranno discusse qui (tra cui un DOM virtuale e l'associazione unidirezionale dei dati, solo per citarne alcuni), il che significa che le idee originate in React stanno già migrando in altri framework. Vedi: The Road to Ember 2.0 RFC - interessante discussione nella richiesta pull di Tom Dale (Data di inizio: 2014-12-03): "In Ember 2.0, adotteremo un" DOM ​​virtuale "e un modello di flusso di dati che abbraccia il migliori idee di React e semplifica la comunicazione tra i componenti ".

Inoltre, Angular.js 2.0 sta implementando molti dei concetti discussi qui.

Aggiornamento 4

Devo approfondire alcune questioni per rispondere a questo commento di Igwe Kalu:

"non è sensato confrontare React (JSX o l'output della compilazione) con JavaScript semplice, quando React alla fine si riduce a JavaScript semplice. [...] Qualunque strategia React utilizzi per l'inserimento DOM può essere applicata senza usare React. Detto questo, non aggiunge alcun vantaggio speciale se si considera la funzionalità in questione oltre alla praticità ". (commento completo qui )

Nel caso in cui non fosse abbastanza chiaro, in parte della mia risposta sto confrontando le prestazioni dell'operare direttamente sul DOM nativo (implementato come oggetti host nel browser) rispetto al DOM falso / virtuale di React (implementato in JavaScript). Il punto che stavo cercando di sottolineare è che il DOM virtuale implementato in JavaScript può superare il vero DOM implementato in C ++ e non che React può superare JavaScript (il che ovviamente non avrebbe molto senso dal momento che è scritto in JavaScript). Il mio punto era che il codice C ++ "nativo" non è sempre garantito per essere più veloce di JavaScript "non nativo". Usare React per illustrare quel punto era solo un esempio.

Ma questo commento ha toccato un problema interessante. In un certo senso è vero che non hai bisogno di alcun framework (React, Angular o jQuery) per qualsiasi motivo (come prestazioni, portabilità, funzionalità) perché puoi sempre ricreare ciò che fa il framework per te e reinventare la ruota - se puoi giustificare il costo, cioè.

Ma - come Dave Smith ha messo bene in Come perdere il punto quando si confrontano le prestazioni del framework Web : "Quando si confrontano due framework Web, la domanda non è: la mia app può essere veloce con il framework X. La domanda è: la mia app sarà veloce con framework X."

Nella mia risposta del 2011 a: Quali sono alcuni motivi tecnici empirici per non usare jQuery Spiego un problema simile, che non è impossibile scrivere un codice di manipolazione DOM portatile senza una libreria come jQuery, ma che le persone raramente lo fanno.

Quando si usano linguaggi di programmazione, librerie o framework, le persone tendono ad usare i modi più convenienti o idiomatici di fare le cose, non quelli perfetti ma scomodi. Il vero valore di buone strutture è rendere facile ciò che altrimenti sarebbe difficile da fare - e il segreto sta nel rendere le cose giuste convenienti. Il risultato ha ancora esattamente lo stesso potere a tua disposizione della forma più semplice di calcolo lambda o della macchina di Turing più primitiva, ma l'espressività relativa di alcuni concetti significa che quegli stessi concetti tendono ad essere espressi più facilmente o affatto, e che le giuste soluzioni non sono solo possibili ma effettivamente implementate ampiamente.

Aggiornamento 5

Reagisci + Prestazioni =? l'articolo di Paul Lewis del luglio 2015 mostra un esempio in cui React è più lento di JavaScript vaniglia scritto a mano per un elenco infinito di immagini di Flickr, che è particolarmente significativo sui dispositivi mobili. Questo esempio mostra che tutti dovrebbero sempre testare le prestazioni per casi d'uso specifici e piattaforme e dispositivi target specifici.

Grazie a Kevin Lozandier per averlo portato alla mia attenzione .


75
questo è quello che chiamo una risposta completa, grazie!
Demwunz,

14
Sembra che Atom si stia allontanando da React. Vedi github.com/atom/atom/issues/3677 .
Juho Vepsäläinen,

6
@ash: se leggi più in basso il thread, parlano di come vorrebbero alla fine allontanarsi completamente da React e altri framework, e semplicemente rotolare i propri usando elementi personalizzati e il DOM shadow.
musicfreak

3
Solo per chiarire la formulazione sopra, nella lista di @ErikAllik, FRP (Functional Reactive Programming) non è un nuovo linguaggio ma piuttosto un approccio che sta guadagnando popolarità. In effetti, "Elm si basa sull'idea della programmazione reattiva funzionale" (da elm-lang.org), e come ha detto, ci sono framework FRP per Haskell, ecc.
Jon Coombs,

5
tl; leggi comunque - risposta brillante e dettagliata!
Mark K Cowan,

16

Polymer è fantastico. React è fantastico. Non sono la stessa cosa.

Polymer è una libreria per la creazione di componenti Web compatibili con versioni precedenti.

React è la V in MVC. È la vista e nient'altro. Almeno da solo.

React non è un framework.

React + Flux + Node + (Gulp o Grunt) è più paragonabile a un framework, ma 3 di queste cose non fanno affatto parte della reazione.

Esistono molte tecnologie, modelli e stili architettonici che reagiscono agli sviluppatori, ma reagire da soli non è un framework.

È triste che nessuno abbia avuto il tempo di dire la cosa più semplice possibile, che non dovrebbero essere confrontati. Hanno alcune sovrapposizioni, ma sono più diverse della stessa.

Entrambi consentono di definire i componenti Web, ma in diversi modi. Oltre a ciò, sono strumenti molto diversi.


React non è M e V, non solo V, poiché contiene e aggiorna lo stato dei dati e rende frammenti di HTML tramite componenti?
abelito,

1
Esistono librerie di gestione dello stato di reazione come flux o redux, ma queste non sono impacchettate con reazioni.
Robotsushi,

Oh, vedo, non consideriamo i dati di visualizzazione come dati di modello ... fino a quando non vengono inviati al lato server. Anche se React mantiene lo stato dei componenti (visualizza i dati), ciò rimane i dati di visualizzazione fino all'invio. Questo ha senso.
abelito,

15

I ragazzi di React hanno una spiegazione abbastanza buona sul confronto tra React e Web Components:

Cercare di confrontare e contrastare React con WebComponents porta inevitabilmente a conclusioni controverse, perché le due librerie sono costruite per risolvere problemi diversi. I componenti Web forniscono un forte incapsulamento per i componenti riutilizzabili, mentre React fornisce una libreria dichiarativa che mantiene il DOM sincronizzato con i dati. I due obiettivi sono complementari; gli ingegneri possono combinare e abbinare le tecnologie. Come sviluppatore, sei libero di utilizzare React nei tuoi WebComponents o di utilizzare WebComponents in React o entrambi.


14

Un'altra risposta in un punto in particolare:

Scrivi JavaScript in vanilla JavaScript, scrivi CSS in CSS, scrivi HTML in HTML.

Nulla ti impedisce di scrivere Javascript, ad esempio, CoffeeScript, TypeScript, ClojureScript o qualsiasi altra cosa. È puramente una questione di preferenza.

HTML è il miglior DSL per documenti HTML statici . Ma non fornisce nulla per HTML dinamico. E nel browser, il miglior linguaggio per rendere dinamico l'HTML è Javascript, non puro HTML con manipolazione del DOM Javascript ad hoc o linguaggio di template come i manubri che non sono nemmeno mezze lingue.

Per CSS, se il tuo CSS è statico, lo scrivi come al solito. Se deve essere dinamico sulla base di alcuni valori di runtime, è la stessa storia di HTML: Javascript è il modo migliore per renderlo dinamico.


1
Apprezzo la risposta, ma non era proprio questo il mio punto. Spero che le mie modifiche abbiano reso la domanda un po 'più chiara?
CletusW

1
Mi dispiace, no. Puoi ancora scrivere il tuo stile in qualsiasi lingua di stili in un file separato. E React JSX fa sembrare che tu stia usando un linguaggio di markup.
DjebbZ,

3
"Javascript è il modo migliore per rendere [CSS] dinamico", semplicemente dicendo che in realtà non spiega il perché.
pilau,

1
Bene, se gli stili / le classi devono cambiare in base all'input dell'utente o alle regole aziendali, basta usare javascript per cambiarli. In vanilla js, dovresti manipolare la classList o le proprietà degli stili di un nodo DOM. Con React puoi raggiungere lo stesso obiettivo manipolando il DOM virtuale. È più chiaro?
DjebbZ,

2
Vjeux, collaboratore principale di React, ha recentemente tenuto un discorso in cui spinge il concetto "CSS in JS" usando React. Penso che sia interessante, potresti essere disposto a vedere di cosa si tratta: blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html
DjebbZ

6

Non ho usato Web Components, ma sembra che richiedano di aggiungere una logica di mutazione codificata manualmente ai gestori di eventi.

frammento dell'esempio Polymer:

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

L'intero punto di React è ridurre la complessità eliminando la logica di mutazione. Invece si rigenera ingenuamente un DOM virtuale e si lascia che l'algoritmo diff di React capisca cosa deve cambiare nel vero DOM.


5
Non sono sicuro di dove hai preso quell'esempio, ma Polymer scoraggia anche la mutazione DOM manuale a favore dell'associazione di dati, anche per i nomi di classe .
CletusW,

È l'esempio della scheda "crea elementi" sulla prima pagina di polymer-project.org .
limscoder

4
Wow, hai ragione! Immagino volessero solo un esempio di ricerca automatica dei nodi. Questo non è probabilmente il migliore da dare, però.
Cletus,

6

Penso che il più grande svantaggio di React secondo me sia che non si basa su standard web. React è uno strumento molto potente in questo momento, ma poiché elude così tanto di ciò che il browser fornisce ogni volta che è possibile, le decisioni che sembravano avere un senso ora probabilmente non avranno senso tra qualche anno poiché le strutture integrate dei browser continuano a Ottimizzare. Quindi vorrei parlarne e come influisce su alcuni aspetti diversi delle applicazioni web.

Prestazione

Alla gente piace sostenere che il vantaggio di React è che reinventa completamente l'intero DOM e il modello di eventi, e il DOM standard esistente è pesante e costoso e cosa no, ma alla fine non ho trovato le prestazioni di Reagisci per essere migliore di quello che riesco a ottenere da un'applicazione Backbone o Polymer ben scritta. In effetti, nella maggior parte della mia esperienza professionale, le prestazioni di React sono state in realtà un po 'peggiori. Questo non vuol dire che React sia lento ... Non è solo la scelta delle prestazioni all'avanguardia che tutti pensavamo fosse prima di metterci le mani sopra.

Nella risposta di rsp, sottolinea che il modello DOM di React per un div ha un peso molto più leggero rispetto al div DOM nativo, e questo è certamente vero. Tuttavia, affinché React sia utile, quel div 'virtuale' deve finire per diventare un vero div ad un certo punto. Quindi, nella mia visione del mondo, non si tratta di un div React contro un div nativo. È un div React + un div nativo contro solo un div nativo. Il sovraccarico della versione di React del DOM non è banale e se gli standard lasciano cadere alcuni di quegli attributi non necessari e consentono ai nodi DOM nativi di essere molto più leggeri, improvvisamente quel sovraccarico sembrerà davvero costoso.

In uno dei miei precedenti posti di lavoro, abbiamo avuto alcune applicazioni in Polymer e alcune applicazioni in React. Una delle prime applicazioni Polymer finì per essere riscritta in React perché era quello su cui la società aveva standard, e sulla base delle misurazioni che ho preso la versione React di questa stessa applicazione si è conclusa usando circa il 30% di memoria in più rispetto alla versione Polymer e sebbene la differenza fosse marginale, anche la versione Polymer è stata resa in meno tempo. Una cosa da considerare qui è che stiamo parlando di applicazioni scritte da persone, e le persone non sono perfette, quindi potrebbe essere possibile che l'implementazione React di questa applicazione non stia sfruttando tutto ciò che React è in grado di fare. Ma penso che almeno in parte abbia a che fare con l'overhead React incorre nell'avere la propria versione del DOM.

React reinventa l'intero DOM utilizzando il proprio modello e quindi lo utilizza per un'importante ottimizzazione delle prestazioni. Una vista viene renderizzata in un DOM virtuale e proiettata nel vero DOM. Quando viene apportata una modifica e la vista deve essere aggiornata, la vista viene nuovamente renderizzata di nuovo in un DOM virtuale e quell'albero viene diffuso rispetto all'albero precedente per determinare quali nodi devono essere modificati nel DOM reale per riflettere questa modifica nella vista. Sebbene questo sia un approccio molto intelligente per effettuare aggiornamenti DOM efficienti, vi è un sovraccarico nel mantenere tutti questi alberi DOM virtuali e diffonderli per determinare cosa modificare nel vero DOM. In questo momento, questo sovraccarico è notevolmente compensato dai vantaggi in termini di prestazioni, ma man mano che il DOM nativo viene migliorato nel tempo, la scala si sposterà nella direzione opposta. Mi preoccupo di come potrebbero invecchiare le app React, e se tra 3 anni saranno molto più lenti delle cose che trattano il DOM in modo più diretto. Questo approccio DOM virtuale è un po 'un martello e altre librerie come Polymer sono state in grado di implementare approcci molto efficienti per gestire il DOM in un modo molto più sottile.

Aggiornamento per le prestazioni: una delle librerie in cui mi sono imbattuto un po 'fa fa quello che penso sia un lavoro migliore nella gestione degli aggiornamenti al DOM. È la libreria Dom incrementale di Google e penso che il fatto che funzioni con il dom sul posto e non debba creare una "copia virtuale" è un approccio molto più pulito, con un sovraccarico di memoria molto inferiore. Scopri di più qui: http://google.github.io/incremental-dom/#about

Componenti dichiarative contro componenti imperative

Una delle cose che senti sempre emergere quando parli di strutturare la tua applicazione sono tutti i vantaggi che i tuoi componenti sono dichiarativi. All'interno della visione del mondo di React, tutto è bello e dichiarativo. Scrivi JavaScript che restituisce markup e React incolla tutto per te. Ed è fantastico se hai a che fare con un'applicazione nuovissima che utilizza solo React e nient'altro. Puoi scrivere alcuni componenti e finché sei all'interno di un pezzo del DOM di proprietà di React, è semplice come mettere quel tag sulla pagina per consumare il tuo componente.

Ma non appena vai a prendere quei componenti e li usi al di fuori di React, le cose diventano molto più complicate. Poiché il modo in cui i componenti di React sono trasformati in tag è completamente al di fuori di ciò che forniscono gli standard web, nientemeno che React sa come darti un modo dichiarativo di consumare questi componenti. Se voglio mettere i componenti di React in una vista Backbone esistente che utilizza i modelli Handlebars, devi renderizzare un div fittizio nel tuo modello con una classe o un ID che puoi usare come handle, quindi scrivere JavaScript imperativo per trovare quel div fittizio e montare il tuo componente in esso. Hai un'applicazione Express.js che utilizza modelli sul lato server? Beh, è ​​la stessa canzone e la stessa danza. Una pagina JSP? Ridi, ma ci sono ancora tantissime applicazioni che le usano ancora. A meno che tu non sia una specie di startup senza codice esistente, tu " dovrai scrivere un po 'di impianto idraulico per riutilizzare i tuoi componenti React in molte applicazioni. Nel frattempo, Polymer raggiunge componenti attraverso lo standard Web Components e, utilizzando le specifiche dell'elemento personalizzato, Polymer è in grado di creare componenti che il browser conosce in modo nativo come consumare. Posso inserire un componente Polymer in una pagina JSP, un modello Express.js, una vista ASP.NET, una vista Backbone ... persino all'interno di un componente React. Letteralmente ovunque puoi usare HTML, puoi consumare un componente Polymer. Le persone che stanno progettando per il riutilizzo guardano agli standard web, perché gli standard sono il contratto che rende facile rendere le cose compatibili tra loro. YouTube continua a creare sempre più contenuti in Polymer (fonte: Polymer raggiunge i componenti attraverso lo standard Web Components e, utilizzando le specifiche dell'elemento personalizzato, Polymer è in grado di creare componenti che il browser conosce in modo nativo come consumare. Posso inserire un componente Polymer in una pagina JSP, un modello Express.js, una vista ASP.NET, una vista Backbone ... persino all'interno di un componente React. Letteralmente ovunque puoi usare HTML, puoi consumare un componente Polymer. Le persone che stanno progettando per il riutilizzo guardano agli standard web, perché gli standard sono il contratto che rende facile rendere le cose compatibili tra loro. YouTube continua a creare sempre più contenuti in Polymer (fonte: Polymer raggiunge i componenti attraverso lo standard Web Components e, utilizzando le specifiche dell'elemento personalizzato, Polymer è in grado di creare componenti che il browser conosce in modo nativo come consumare. Posso inserire un componente Polymer in una pagina JSP, un modello Express.js, una vista ASP.NET, una vista Backbone ... persino all'interno di un componente React. Letteralmente ovunque puoi usare HTML, puoi consumare un componente Polymer. Le persone che stanno progettando per il riutilizzo guardano agli standard web, perché gli standard sono il contratto che rende facile rendere le cose compatibili tra loro. YouTube continua a creare sempre più contenuti in Polymer (fonte: Posso inserire un componente Polymer in una pagina JSP, un modello Express.js, una vista ASP.NET, una vista Backbone ... persino all'interno di un componente React. Letteralmente ovunque puoi usare HTML, puoi consumare un componente Polymer. Le persone che stanno progettando per il riutilizzo guardano agli standard web, perché gli standard sono il contratto che rende facile rendere le cose compatibili tra loro. YouTube continua a creare sempre più contenuti in Polymer (fonte: Posso inserire un componente Polymer in una pagina JSP, un modello Express.js, una vista ASP.NET, una vista Backbone ... anche all'interno di un componente React. Letteralmente ovunque puoi usare HTML, puoi consumare un componente Polymer. Le persone che stanno progettando per il riutilizzo guardano agli standard web, perché gli standard sono il contratto che rende facile rendere le cose compatibili tra loro. YouTube continua a creare sempre più contenuti in Polymer (fonte:http://react-etc.net/entry/youtube-is-being-rebuilt-on-web-components-and-polymer ), e posso solo immaginare che l'aspetto polimerico basato sugli standard sia il motivo. Quel player di YouTube al centro della pagina di YouTube potrebbe essere trasformato in un componente che include una fonte di contenuti come proprietà e improvvisamente chiunque voglia incorporare il player di YouTube nella propria pagina può letteralmente usare esattamente lo stesso codice di player che YouTube sta usando e possono farlo semplicemente attaccando un tag nella loro pagina.

Sommario

Vedo che ci sono sicuramente alcuni aspetti interessanti di React in questo momento. Se tutto ciò che stai utilizzando è React, puoi creare alcuni widget e alcuni componenti e riutilizzarli in modo dichiarativo ovunque. Ma penso che React sarebbe stato molto meglio se avrebbe usato alcuni degli standard di Web Components per ottenere ciò che fa, invece di spegnersi e costruire un browser all'interno di un browser e un meccanismo complesso per mantenere tutto sincronizzato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.