Vor- und Nachteile von Facebooks Reaktion im Vergleich zu Webkomponenten (Polymer)


521

Was sind die Hauptvorteile von Facebooks React gegenüber der kommenden Web Components- Spezifikation und umgekehrt (oder ein Vergleich von Äpfeln zu Äpfeln mit der Polymer- Bibliothek von Google )?

Laut diesem EU-Vortrag von JSConf und der React-Homepage sind die Hauptvorteile von React:

  • Entkopplung und erhöhte Kohäsion anhand eines Komponentenmodells
  • Abstraktion, Komposition und Expressivität
  • Virtuelle DOM- und synthetische Ereignisse (was im Grunde bedeutet, dass sie das DOM und sein Ereignissystem vollständig neu implementiert haben)
    • Aktiviert modernes HTML5-Ereignismaterial in IE 8
    • Serverseitiges Rendering
    • Testbarkeit
    • Bindungen an SVG, VML und <canvas>

Mit Ausnahme dieses virtuellen DOM-Konzepts wird fast alles Native über Web Components in Browser integriert. Ich kann sehen, wie nützlich das virtuelle DOM und synthetische Ereignisse heutzutage sein können, um alte Browser zu unterstützen, aber wirft man nicht einen großen Teil des nativen Browser-Codes weg, als würde man sich langfristig in den Fuß schießen? Ist das für moderne Browser nicht eine Menge unnötiger Overhead / Neuerfindung des Rads?

Hier sind einige Dinge, von denen ich denke, dass React fehlt, die Web Components für Sie erledigen wird. Korrigiere mich, wenn ich falsch liege.

  • Native Browser-Unterstützung (lesen Sie "garantiert schneller")
  • Schreiben Sie Skripte in einer Skriptsprache, schreiben Sie Stile in einer Stilsprache, schreiben Sie Markups in einer Markupsprache.
  • Stilkapselung mit Shadow DOM
    • React hat stattdessen dies , was das Schreiben von CSS in JavaScript erfordert. Nicht hübsch.
  • Bidirektionale Bindung

12
Wrt. Zwei-Wege-Bindung. Diese Funktion ist im Maßstab problematisch. In trivialen Fällen funktioniert es gut, in realen Fällen müssen Sie jedoch in der Regel ein Ansichtsmodell verwenden, um den Code handhabbar zu halten, anstatt ihn an das tatsächliche Modell zu binden. Dadurch ist die bidirektionale Bindung weitaus weniger nützlich als es schien zunächst. Ich denke, es kann ein Vorteil von React sein, dass es keine bidirektionale Bindung bietet, da es eine ordnungsgemäße Datenflussarchitektur erzwingt.
Joeri Sebrechts

8
Ich habe mir React, Angular und Knockout angesehen. Ich finde Knockout am 'saubersten' in Bezug auf die Trennung von Vorlagen, Daten und Bindung. Ich wollte gerne reagieren, aber als ich versuchte, eine einfache Combobox zu erstellen, stellte ich fest, dass ich viel mehr Code schrieb und Renderlogik mit HTML-Templaten mischte. Mir scheint, diese Bibliotheken / Apis bewegen uns rückwärts und nicht vorwärts. Das Beste an React ist die virtuelle Dom-Manipulation, aber ich kann sehen, dass es früher als später zu anderen etablierten Frameworks kommt.
mike01010

41
Ich bin sehr überrascht (und auch erfreut!), Dass diese Frage nicht als "primär meinungsbasiert" abgestellt wurde.
Iconoclast

4
Es ist nicht möglich, "Skript in einer Skriptsprache" und "Markup in einer Markup-Sprache" zu schreiben, wenn Sie Vorlagen beliebiger Art erstellen. Angular, Polymer usw. verwenden eine in HTML eingebettete DSL-Vorlage. React verwendet eine in JS (JSX) eingebettete DSL-Vorlage. Das Problem beim Einbetten einer DSL in HTML besteht darin, wie der Bereich zum Abrufen von Werten von der JS festgelegt werden kann. Dies führt zu Angulars komplexem $ scope-System. In JSX hingegen ist der Gültigkeitsbereich von Variablen in Vorlagen nur der Gültigkeitsbereich von JS - ich finde ihn viel weniger verwirrend.
Andy

3
Momentan sind React-Komponenten (sofern sie nicht schlecht geschrieben sind) in DOM-gebundenen Frameworks schneller als die gleichen. Das V-Doming und die unterschiedliche Magie ist das Alleinstellungsmerkmal des Reagierens. Mein Punkt ist - warum sollten die Brower nicht einen Unterschied wie diesen in ihrem nativen Featureset bauen? Was sie aufhält, und wenn nichts sie aufhält, wird die Führung von React wahrscheinlich von kurzer Dauer sein.
Fasttrainofthoughts

Antworten:


664

Update:  Diese Antwort scheint ziemlich beliebt zu sein, daher habe ich mir etwas Zeit genommen, um sie ein wenig aufzuräumen, neue Informationen hinzuzufügen und einige Dinge zu klären, von denen ich dachte, dass sie nicht klar genug sind. Bitte kommentieren Sie, wenn Sie der Meinung sind, dass weitere Informationen oder Updates erforderlich sind.

Die meisten Ihrer Anliegen sind wirklich eine Frage der Meinung und der persönlichen Präferenz, aber ich werde versuchen, so objektiv wie möglich zu antworten:

Native vs. Compiled

Schreiben Sie JavaScript in Vanille-JavaScript, schreiben Sie CSS in CSS, schreiben Sie HTML in HTML.

Damals gab es heftige Debatten darüber, ob man native  Assembly von Hand schreiben oder eine höhere Sprache wie C verwenden sollte, damit der Compiler Assembly-Code für Sie generiert. Schon vorher weigerten sich die Leute, Assemblern zu vertrauen , und zogen es vor, systemeigenen Maschinencode von Hand zu schreiben ( und ich mache keine Witze ).

Mittlerweile gibt es viele Leute, die HTML in Haml oder Jade , CSS in Sass oder Less und JavaScript in CoffeeScript oder TypeScript schreiben . Es ist da. Es klappt. Manche Leute bevorzugen es, andere nicht.

Der Punkt ist, dass es nichts grundsätzlich Falsches ist, kein JavaScript in Vanille-JavaScript, kein CSS in CSS und kein HTML in HTML zu schreiben. Es ist wirklich eine Frage der Präferenz.

Interne und externe DSLs

 Bei der Stilkapselung mit Shadow DOM React muss stattdessen CSS in JavaScript geschrieben werden. Nicht hübsch.

Schön oder nicht, es ist sicherlich ausdrucksstark. JavaScript ist eine sehr leistungsfähige Sprache, die viel leistungsfähiger ist als CSS (einschließlich aller CSS-Präprozessoren). Es hängt davon ab, ob Sie für diese Art von Dingen interne oder externe DSLs bevorzugen. Auch hier eine Frage der Präferenz.

(Hinweis: Ich habe über die Inline-Stile in React gesprochen , auf die in der ursprünglichen Frage verwiesen wurde.)

Arten von DSLs - Erklärung

Update: Nachdem ich meine Antwort einige Zeit nach dem Schreiben gelesen habe, denke ich, dass ich erklären muss, was ich hier meine. DSL ist eine domänenspezifische Sprache und kann entweder intern (unter Verwendung der Syntax der Hostsprache wie JavaScript - wie zum Beispiel React without JSX oder wie die oben erwähnten Inline-Stile in React) oder extern (unter Verwendung einer anderen Syntax) sein als die Host-Sprache - wie in diesem Beispiel würde CSS (eine externe DSL) in JavaScript inlinieren).

Dies kann verwirrend sein, da in einigen Literaturstellen andere Begriffe als "intern" und "extern" verwendet werden, um solche DSL-Typen zu beschreiben. Manchmal wird anstelle von „internen“ „embedded“ verwendet , aber das Wort „embedded“ kann verschiedene Dinge bedeutet - zum Beispiel Lua wird beschrieben als „Lua: eine erweiterbare eingebettete Sprache“ , wo eingebettet hat nichts mit eingebettetem (intern) DSL zu tun (in In diesem Sinne ist es genau umgekehrt (ein externes DSL), aber es bedeutet, dass es in dem gleichen Sinne eingebettet ist, wie beispielsweise SQLite eine eingebettete Datenbank ist. Es gibt sogar eLua, wo "e" in einem dritten Sinne für "eingebettet" steht - das ist für eingebettete Systeme gedacht! Deshalb verwende ich den Begriff "eingebettetes DSL" nicht gern, weil Dinge wie eLua "DSLs" sein können, die in zweierlei Hinsicht "eingebettet" sind, aber überhaupt kein "eingebettetes DSL" sind!

Erschwerend kommt hinzu, dass einige Projekte noch mehr Verwirrung stiften. Z.B. Flatiron-Vorlagen werden als "DSL-frei" bezeichnet, obwohl dies nur ein perfektes Beispiel für ein internes DSL mit folgender Syntax ist:map.where('href').is('/').insert('newurl');

Allerdings, als ich schrieb "JavaScript ist eine sehr mächtige Sprache, viel mächtiger als CSS (sogar mit einem der CSS-Präprozessoren). Es hängt davon ab, ob Sie interne oder externe DSLs für solche Dinge bevorzugen. eine Frage der Präferenz. " Ich habe über diese beiden Szenarien gesprochen:

Ein:

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

Zwei:

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

Das erste Beispiel verwendet das, was in der Frage beschrieben wurde als: "Schreiben von CSS in JavaScript. Nicht schön." Das zweite Beispiel verwendet Sass. Ich bin damit einverstanden, dass die Verwendung von JavaScript zum Schreiben von CSS möglicherweise nicht hübsch ist (für einige Definitionen von "hübsch"), aber es gibt einen Vorteil, dies zu tun.

Ich kann Variablen und Funktionen in Sass haben, aber sind sie lexikalisch oder dynamisch? Sind sie statisch oder dynamisch typisiert? Stark oder schwach? Was ist mit den numerischen Typen? Typumwandlung? Welche Werte sind wahr und welche falsch? Kann ich Funktionen höherer Ordnung haben? Rekursion? Schwanz ruft? Lexikalische Verschlüsse? Werden sie in normaler Reihenfolge oder in anwendbarer Reihenfolge bewertet? Gibt es eine faule oder eifrige Bewertung? Werden Argumente zu Funktionen als Wert oder als Referenz übergeben? Sind sie veränderlich? Unveränderlich? Hartnäckig? Was ist mit Objekten? Klassen? Prototypen? Erbe?

Das sind keine trivialen Fragen und dennoch muss ich Antworten auf sie wissen, wenn ich Sass- oder Less-Code verstehen will. Ich kenne diese Antworten für JavaScript bereits, was bedeutet, dass ich bereits jede interne DSL (wie die Inline-Stile in React) auf diesen Ebenen verstehe. Wenn ich also React verwende, muss ich nur eine Reihe von Antworten auf diese (und viele ähnliche) kennen ) fragen, während ich bei zb. Sass und Lenker Dann muss ich drei Sätze dieser Antworten kennen und ihre Auswirkungen verstehen.

Es ist nicht so, dass die eine oder andere Weise immer besser ist, aber jedes Mal, wenn Sie eine andere Sprache in den Mix einführen, zahlen Sie einen Preis, der auf den ersten Blick nicht so offensichtlich ist, und dieser Preis ist Komplexität.

Ich hoffe, ich habe geklärt, was ich ursprünglich ein bisschen gemeint habe.

Datenbindung

Bidirektionale Bindung

Dies ist ein wirklich interessantes Thema und in der Tat auch eine Frage der Präferenz. Beidseitig ist nicht immer besser als einseitig. Es ist eine Frage, wie Sie den veränderlichen Zustand in Ihrer Anwendung modellieren möchten. Ich habe bidirektionale Bindungen immer als eine Idee angesehen, die den Prinzipien der funktionalen Programmierung etwas zuwiderläuft, aber funktionale Programmierung ist nicht das einzige Paradigma, das funktioniert. Einige Leute bevorzugen diese Art von Verhalten, und beide Ansätze scheinen in der Praxis ziemlich gut zu funktionieren. Wenn Sie sich für die Details der Entwurfsentscheidungen im Zusammenhang mit der Modellierung des Zustands in React interessieren, sehen Sie sich den Vortrag von Pete Hunt (in der Frage verlinkt) und den Vortrag von Tom Occhino und Jordan Walke an  , die ihn sehr gut erklären meine Meinung.

Update: Siehe auch einen weiteren Vortrag von Pete Hunt: Sei vorhersehbar, nicht korrekt: Funktionale DOM-Programmierung .

Update 2: Es ist erwähnenswert, dass viele Entwickler gegen den bidirektionalen Datenfluss oder die bidirektionale Bindung argumentieren , manche nennen es sogar ein Anti-Pattern. Nehmen wir zum Beispiel die Flux- Anwendungsarchitektur, die explizit das MVC- Modell (das sich für große Facebook- und Instagram-Anwendungen als schwer skalierbar erwiesen hat) zugunsten eines streng unidirektionalen Datenflusses vermeidet (siehe Hacker Way: Überdenken der Web-App-Entwicklung bei Facebook talk by) Tom Occhino, Jing Chen und Pete Hunt für eine gute Einführung). Auch viel Kritik gegen AngularJS (Das beliebteste Webframework, das lose auf dem MVC-Modell basiert und für die bidirektionale Datenbindung bekannt ist) enthält Argumente gegen diesen bidirektionalen Datenfluss, siehe:

Update 3: Ein weiterer interessanter Artikel, der einige der oben diskutierten Probleme gut erklärt, ist die Dekonstruktion von ReactJSs Flux - Keine Verwendung von MVC mit ReactJS von Mikael Brassman, Autor von RefluxJS (einer einfachen Bibliothek für unidirektionale Datenfluss-Anwendungsarchitektur, die von Flux inspiriert ist).

Update 4: Ember.js entfernt sich derzeit von der bidirektionalen Datenbindung und wird in zukünftigen Versionen standardmäßig in eine Richtung ausgeführt. Siehe: Die Zukunft von Ember Vortrag von Stefan Penner vom Embergarten Symposium in Toronto am 15. November 2014.

Update 5: Siehe auch: Der Weg zu Ember 2.0 RFC - interessante Diskussion in der Pull-Anfrage von Tom Dale :

"Als wir die ursprüngliche Vorlagenebene entwarfen, stellten wir fest, dass die bidirektionale Bindung aller Daten nicht sehr schädlich ist. Wenn Sie keine bidirektionale Bindung festlegen, handelt es sich de facto um eine einseitige Bindung!

Seitdem haben wir (mit der Hilfe unserer Freunde bei React) festgestellt, dass Komponenten Daten an ihre Kinder weitergeben möchten, ohne sich vor abwegigen Mutationen hüten zu müssen.

Darüber hinaus wird die Kommunikation zwischen Komponenten häufig auf natürliche Weise als Ereignis oder Rückruf ausgedrückt . Dies ist in Ember möglich, aber die Dominanz von bidirektionalen Datenbindungen führt Menschen häufig dazu, bidirektionale Bindungen als Kommunikationskanal zu verwenden . Erfahrene Ember-Entwickler machen diesen Fehler (normalerweise) nicht, aber er ist einfach zu begehen. " [Hervorhebung hinzugefügt]

Native vs. VM

Native Browser-Unterstützung (lesen Sie "garantiert schneller")

Nun endlich etwas, das keine Ansichtssache ist.

Eigentlich ist es hier genau umgekehrt. Natürlich kann "nativer" Code in C ++ geschrieben werden, aber in was sind die JavaScript-Engines Ihrer Meinung nach geschrieben?

Tatsächlich sind die JavaScript-Engines in den Optimierungen, die sie heute verwenden, wirklich erstaunlich - und nicht nur V8, sondern auch SpiderMonkey und sogar Chakra glänzen heutzutage. Beachten Sie, dass der Code bei JIT-Compilern nicht nur so nativ ist, wie er möglicherweise sein kann, sondern auch Möglichkeiten zur Laufzeitoptimierung bietet, die in statisch kompiliertem Code einfach nicht möglich sind.

Wenn Leute denken, dass JavaScript langsam ist, meinen sie normalerweise JavaScript, das auf das DOM zugreift. Das DOM ist langsam. Es ist nativ, in C ++ geschrieben und ist aufgrund der Komplexität, die es implementieren muss, höllisch langsam.

Öffne deine Konsole und schreibe:

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

und sehen, wie viele Eigenschaften ein leeres divElement, das nicht einmal an das DOM angehängt ist, implementieren muss. Dies sind nur die  Eigenschaften der ersten Ebene , die "eigene Eigenschaften" sind, dh. nicht von der Prototypenkette geerbt:

ausrichten, abwarten, aufVolumenändern, aufUpdate, aufhängen, einreichen, aufinstalliert, aufzeigen, aufwählen, aufsuchen, aufgesucht, aufrollen, aufgrösse, aufsetzen, auftauschen, auffortschritt, aufspielen, aufspielen, aufhören, aufmausen, aufmausen, aufmausen onmouseenter, onmousedown, onloadstart, onloadedmetadata, onloadeddata, onload, onkeyup, onkeypress, onkeydown, oninvalid, oninput, onfocus, onerror, onended, onemptied, ondurationchange, ondrop, ondragstart, ondragover, ondragleave, ondragdragd oncontextmenu, onclose, onclick, onchange, oncanplaythrough, oncanplay, oncancel, onblur, onabort, rechtschreibprüfung, isContentEditable, contentEditable, outerText, innerText, accessKey, hidden, webkitdropzone, draggable, tabIndex, dir, translate, langCild, lastE child, tabIndexfirstElementChild, children, nextElementSibling, previousElementSibling, onwheel, onwebkitfullscreenerror, onwebkitfullscreenchange, onselectstart, onsearch, onpaste, oncut, oncopy, onbeforepaste, onbeforecut, onbeforecopy, onbeforecopy clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offsetTop, offsetLeft, localName, Präfix, NamespaceURI, ID, Stil, Attribute, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, firstCildhild parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, Dataset, Klassenliste, Klassenname, OuterHTML, InnerHTML, ScrollHeight, ScrollWidth, ScrollTop, ScrollLeft, ClientHeight, ClientWidth, ClientTop, ClientLeftH OffsetWidthParent NamespaceURI, ID, Stil, Attribute, TagName, ParentElement, TextContent, BaseURI, OwnerDocument, NextSibling, PreviousSibling, LastChild, FirstChild, ChildNodes, ParentNode, NodeType, NodeValue, NodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, Dataset, Klassenliste, Klassenname, OuterHTML, InnerHTML, ScrollHeight, ScrollWidth, ScrollTop, ScrollLeft, ClientHeight, ClientWidth, ClientTop, ClientLeftH OffsetWidthParent NamespaceURI, ID, Stil, Attribute, 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

Viele von ihnen sind tatsächlich verschachtelte Objekte - um die (eigenen) Eigenschaften eines leeren Native divin Ihrem Browser zu sehen, sehen Sie sich diese Geige an .

Ich meine ernsthaft, onvolumechange Eigenschaft auf jedem einzelnen div Knoten? Ist das ein Fehler? Nein, es ist nur eine traditionelle DOM Level 0-Ereignismodellversion eines der Ereignishandler, " die von allen HTML-Elementen unterstützt werden muss , sowohl als Inhaltsattribute als auch als IDL-Attribute" [Hervorhebung hinzugefügt] in Abschnitt 6.1.6.2 der HTML-Spezifikation von W3C - kein Weg daran vorbei.

In der Zwischenzeit sind dies die Eigenschaften der ersten Ebene eines Fake-DOM divin React:

Requisiten, _Besitzer, _LifeCycleState, _pendingProps, _pendingCallbacks, _pendingOwner

Ein ziemlicher Unterschied, nicht wahr? In der Tat ist dies das gesamte Objekt zu JSON (serialisiert LIVE - DEMO ), weil hey Sie tatsächlich kann  es zu JSON serialisiert werden, da es keine zirkulären Referenzen enthält - etwas undenkbar in der Welt der nativen DOM ( wo es nur eine Ausnahme auslösen würde ):

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

Dies ist so ziemlich der Hauptgrund, warum React schneller sein kann als das native Browser-DOM - weil es dieses Durcheinander nicht implementieren muss .

In dieser Präsentation von Steven Luscher erfahren Sie , was schneller ist: Natives DOM in C ++ oder gefälschtes DOM, das vollständig in JavaScript geschrieben ist. Es ist eine sehr faire und unterhaltsame Präsentation.

Update: Ember.js wird in zukünftigen Versionen ein virtuelles DOM verwenden, das stark von React inspiriert ist, um die Leistung zu verbessern. Siehe: Die Zukunft von Ember Vortrag von Stefan Penner vom Embergarten Symposium in Toronto am 15. November 2014.

Zusammenfassend lässt sich sagen, dass Features von Webkomponenten wie Vorlagen, Datenbindungen oder benutzerdefinierte Elemente viele Vorteile gegenüber React bieten. Solange das Dokumentobjektmodell selbst nicht erheblich vereinfacht wird, ist die Leistung keine davon.

Aktualisieren

Zwei Monate nachdem ich diese Antworten gepostet hatte, gab es einige Neuigkeiten, die hier relevant sind. Wie ich gerade auf Twitter geschrieben habe , nutzt die neueste Version des Atom- Texteditors, der von GitHub in JavaScript geschrieben wurde, Facebooks React, um eine bessere Leistung zu erzielen, obwohl laut Wikipedia "Atom auf Chrom basiert und in C ++ geschrieben" die volle Kontrolle über hat die native C ++ - DOM-Implementierung (siehe The Nucleus of Atom ) und Web Components werden garantiert unterstützt, da es mit einem eigenen Webbrowser ausgeliefert wird. Es ist nur ein aktuelles Beispiel für ein reales Projekt, das jede andere Art von Optimierung hätte verwenden können, die für Webanwendungen normalerweise nicht verfügbar ist, und es hat sich dennoch für die Verwendung von React entschieden, das selbst in JavaScript geschrieben ist, um die beste Leistung zu erzielen, obwohl Atom wurde ursprünglich nicht mit React erstellt, daher war es keine triviale Änderung.

Update 2

Es ist ein interessanter Vergleich von Todd Parker mit Webpage Leistung vergleichen TodoMVC in Angular, Backbone geschrieben Beispiele, Ember, Polymer, CanJS, YUI, Knockout, Reaktion und Shoestring. Dies ist der objektivste Vergleich, den ich bisher gesehen habe. Was hier von Bedeutung ist, ist, dass alle entsprechenden Beispiele von Experten in all diesen Frameworks geschrieben wurden, alle auf GitHub verfügbar sind und von jedem verbessert werden können, der denkt, dass ein Teil des Codes für eine schnellere Ausführung optimiert werden könnte.

Update 3

Ember.js wird in zukünftigen Versionen eine Reihe von Funktionen von React enthalten, die hier behandelt werden (einschließlich eines virtuellen DOM und einer unidirektionalen Datenbindung, um nur einige zu nennen). Dies bedeutet, dass die aus React stammenden Ideen bereits in andere Frameworks migriert werden. Siehe: Der Weg zu Ember 2.0 RFC - interessante Diskussion in der Pull-Anfrage von Tom Dale (Startdatum: 03.12.2014): "In Ember 2.0 werden wir ein" virtuelles DOM "- und Datenflussmodell übernehmen, das die Die besten Ideen von Reagieren und vereinfachen die Kommunikation zwischen Komponenten. "

Auch Angular.js 2.0 implementiert viele der hier diskutierten Konzepte.

Update 4

Ich muss auf einige Punkte eingehen, um diesen Kommentar von Igwe Kalu zu beantworten:

"Es ist nicht sinnvoll, React (JSX oder die Kompilierungsausgabe) mit reinem JavaScript zu vergleichen, wenn React letztendlich auf reinem JavaScript reduziert wird. [...] Jede Strategie, die React für das Einfügen von DOMs verwendet, kann ohne React angewendet werden bringt keine besonderen Vorteile mit sich, wenn man die fragliche Funktion außer der Bequemlichkeit betrachtet. " (vollständiger Kommentar hier )

Für den Fall, dass es nicht klar genug war, vergleiche ich in einem Teil meiner Antwort die Leistung des direkten Betriebs auf dem nativen DOM (implementiert als Host-Objekte im Browser) mit dem gefälschten / virtuellen DOM von React (implementiert in JavaScript). Der Punkt, den ich anstrebte, ist, dass das in JavaScript implementierte virtuelle DOM das in C ++ implementierte reale DOM übertreffen kann und nicht, dass React JavaScript übertreffen kann (was offensichtlich keinen Sinn ergibt , da es in JavaScript geschrieben ist). Mein Punkt war, dass "nativer" C ++ - Code nicht immer schneller ist als "nicht nativer" JavaScript. Die Verwendung von React zur Veranschaulichung dieses Punktes war nur ein Beispiel.

Dieser Kommentar berührte jedoch ein interessantes Thema. In gewissem Sinne ist es wahr, dass Sie aus keinem Grund (wie Leistung, Portabilität, Funktionen) ein Framework (React, Angular oder jQuery) benötigen, da Sie jederzeit neu erstellen können, was das Framework für Sie tut, und das Rad neu erfinden können - wenn Sie können also die Kosten rechtfertigen.

Aber - wie Dave Smith legt es schön in Wie der Punkt verpassen , wenn Web - Framework zum Vergleich der Leistung : „Wenn zwei Frameworks Web zu vergleichen, ist die Frage nicht , kann mein app mit Rahmen X. schnell seine Die Frage ist wird mein app schnell mit Rahmen X."

In meiner Antwort von 2011 auf: Was sind einige empirische technische Gründe, um jQuery nicht zu verwenden? Ich erkläre ein ähnliches Problem, dass es nicht unmöglich ist, portablen DOM-Manipulationscode ohne eine Bibliothek wie jQuery zu schreiben, dies jedoch nur selten der Fall ist.

Bei der Verwendung von Programmiersprachen, Bibliotheken oder Frameworks tendieren die Leute dazu, die bequemsten oder idiomatischsten Methoden zu verwenden, nicht die perfekten, sondern die unbequemsten. Der wahre Wert guter Frameworks besteht darin, einfach zu machen, was sonst schwer zu tun wäre - und das Geheimnis besteht darin, die richtigen Dinge bequem zu machen. Das Ergebnis ist, dass Ihnen immer noch genau die gleiche Kraft zur Verfügung steht wie bei der einfachsten Form der Lambda-Rechnung oder der primitivsten Turing-Maschine. Die relative Aussagekraft bestimmter Konzepte führt jedoch dazu, dass genau diese Konzepte leichter oder gar nicht zum Ausdruck gebracht werden Die richtigen Lösungen sind nicht nur möglich, sondern werden auch in großem Umfang umgesetzt.

Update 5

Reagieren + Leistung =? Der Artikel von Paul Lewis aus dem Juli 2015 zeigt ein Beispiel, in dem React langsamer ist als Vanille. JavaScript wurde von Hand für eine unendliche Liste von Flickr-Bildern geschrieben, was besonders für Mobilgeräte von Bedeutung ist. Dieses Beispiel zeigt, dass jeder die Leistung immer für bestimmte Anwendungsfälle und bestimmte Zielplattformen und -geräte testen sollte.

Dank Kevin Lozandier für ihn , um meine Aufmerksamkeit zu bringen .


75
das nenne ich eine umfassende antwort, danke!
Demwunz

14
Sieht so aus, als würde sich Atom von React entfernen. Siehe github.com/atom/atom/issues/3677 .
Juho Vepsäläinen

6
@ash: Wenn Sie weiter unten im Thread nachlesen, sprechen sie darüber, wie sie sich irgendwann vollständig von React und anderen Frameworks entfernen möchten, und rollen einfach ihre eigenen mit benutzerdefinierten Elementen und dem Schatten-DOM.
Musicfreak

3
Um den obigen Wortlaut zu verdeutlichen, ist FRP (Functional Reactive Programming) in der Liste von @ErikAllik keine neue Sprache, sondern ein Ansatz, der an Beliebtheit gewinnt. Tatsächlich basiert "Elm auf der Idee des funktionalen reaktiven Programmierens" (von elm-lang.org), und wie er sagte, gibt es FRP-Frameworks für Haskell usw.
Jon Coombs,

5
Trotzdem lesen - brillante, detaillierte Antwort!
Mark K Cowan

16

Polymer ist großartig. Die Reaktion ist großartig. Sie sind nicht dasselbe.

Polymer ist eine Bibliothek zum Erstellen abwärtskompatibler Webkomponenten.

Reagiere ist das V in MVC. Es ist die Aussicht und sonst nichts. Zumindest nicht von alleine.

Reagieren ist kein Rahmen.

React + Flux + Node + (Gulp oder Grunt) ist vergleichbarer mit einem Framework, aber 3 dieser Dinge sind überhaupt nicht Teil von React.

Es gibt viele Technologien, Muster und Architekturstile, denen Entwickler folgen, aber die Reaktion selbst ist kein Framework.

Es ist traurig, dass sich niemand die Zeit genommen hat, um das Einfachste zu sagen, dass sie nicht verglichen werden sollten. Sie haben einige Überlappungen, aber sie sind unterschiedlicher als die gleichen.

Mit beiden können Sie Webkomponenten auf unterschiedliche Weise definieren. Darüber hinaus sind sie sehr, sehr unterschiedliche Werkzeuge.


Reagiert nicht sowohl das M als auch das V, nicht nur das V, da es den Datenzustand enthält und aktualisiert und Fragmente von HTML über Komponenten rendert?
Abelito

1
Es gibt Bibliotheken zur Verwaltung von Reaktionszuständen wie Flux oder Redux, aber diese sind nicht mit React gepackt.
Robotsushi

Oh, ich verstehe, wir betrachten die Ansichtsdaten nicht als Modelldaten, bis sie auf der Serverseite übermittelt werden. Obwohl React den Komponentenzustand (Daten anzeigen) beibehält, bleiben die Anzeigedaten bis zum Senden erhalten. Das macht Sinn.
Abelito

15

Die React-Leute haben eine ziemlich gute Erklärung für den Vergleich zwischen React und Web Components:

Der Versuch, mit WebComponents zu vergleichen und zu kontrastieren, führt unweigerlich zu falschen Schlussfolgerungen, da die beiden Bibliotheken unterschiedliche Probleme lösen sollen. WebComponents bietet eine starke Kapselung für wiederverwendbare Komponenten, während React eine deklarative Bibliothek bereitstellt, die das DOM mit Ihren Daten synchronisiert. Die beiden Ziele ergänzen sich; Ingenieure können die Technologien kombinieren. Als Entwickler können Sie entweder React in Ihren WebComponents oder WebComponents in React oder beides verwenden.


14

Eine weitere Antwort in einem Punkt speziell:

Schreiben Sie JavaScript in Vanille-JavaScript, schreiben Sie CSS in CSS, schreiben Sie HTML in HTML.

Nichts hindert Sie daran, Javascript in etwa CoffeeScript, TypeScript, ClojureScript oder etwas anderem zu schreiben. Es ist nur eine Frage der Präferenz.

HTML ist die beste DSL für statische HTML-Dokumente. Es bietet jedoch nichts für dynamisches HTML. Und im Browser ist die beste Sprache, um HTML dynamisch zu machen, Javascript, nicht reines HTML mit Ad-hoc-Javascript-DOM-Manipulation oder Vorlagensprache wie Lenker, die nicht einmal halbe Sprachen sind.

Wenn Ihr CSS für CSS statisch ist, schreiben Sie es wie gewohnt. Wenn es dynamisch sein muss, basierend auf einigen Laufzeitwerten, ist es die gleiche Geschichte wie HTML: Javascript ist der beste Weg, um es dynamisch zu machen.


1
Ich weiß die Antwort zu schätzen, aber das war eigentlich nicht mein Punkt. Hoffentlich haben meine Änderungen die Frage etwas klarer gemacht?
CletusW

1
Entschuldigung nicht. Sie können Ihren Stil weiterhin in einer separaten Datei in einer beliebigen Stilsprache schreiben. Und mit Reacts JSX sieht es so aus, als würden Sie eine Auszeichnungssprache verwenden.
DjebbZ

3
"Javascript ist der beste Weg, um [CSS] dynamisch zu machen" - einfach zu sagen, erklärt nicht wirklich warum.
Pilau

1
Nun, wenn sich die Stile / Klassen gemäß Benutzereingaben oder Geschäftsregeln ändern müssen, verwenden Sie einfach Javascript, um sie zu ändern. In Vanilla Js würden Sie die Klassenlisten- oder Stileigenschaften eines DOM-Knotens bearbeiten. Mit React können Sie dasselbe Ziel erreichen, indem Sie das virtuelle DOM manipulieren. Ist es klarer?
DjebbZ

2
Vjeux, der Hauptverantwortliche für React, hat kürzlich einen Vortrag gehalten, in dem er das "CSS in JS" -Konzept mit React vorantreibt. Ich finde es interessant, vielleicht sind Sie bereit zu sehen, worum es geht: blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html
DjebbZ

6

Ich habe keine Webkomponenten verwendet, aber es sieht so aus, als müssten Sie Ereignishandlern manuell codierte Mutationslogik hinzufügen.

Ausschnitt aus dem Polymer-Beispiel:

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

Der springende Punkt bei React ist die Reduzierung der Komplexität durch Eliminierung der Mutationslogik. Stattdessen generieren Sie ein virtuelles DOM auf einfache Weise neu und lassen den Diff-Algorithmus von React herausfinden, was im realen DOM geändert werden muss.


5
Ich bin mir nicht sicher, woher Sie dieses Beispiel haben, aber Polymer rät auch von manueller DOM-Mutation zugunsten der Datenbindung ab, auch für Klassennamen .
CletusW

Dies ist das Beispiel auf der Registerkarte "Elemente erstellen" auf der Startseite von polymer-project.org .
Limscoder

4
Wow, du hast recht! Ich denke, sie wollten nur ein Beispiel für die automatische Knotensuche. Das ist aber wahrscheinlich nicht das Beste, was man geben kann.
CletusW

6

Ich denke, der größte Nachteil von React ist meiner Meinung nach, dass es nicht auf Webstandards basiert. React ist derzeit ein sehr leistungsfähiges Tool, aber da es so viel von dem, was der Browser bietet, umgeht, werden Entscheidungen, die jetzt sinnvoll zu sein schienen, wahrscheinlich in ein paar Jahren keinen Sinn ergeben, da die eingebauten Funktionen des Browsers weiterhin funktionieren verbessern. Daher möchte ich darüber sprechen und erläutern, wie sich dies auf einige verschiedene Aspekte von Webanwendungen auswirkt.

Performance

Die Leute argumentieren gerne, dass Reacts Vorteil darin besteht, dass das gesamte DOM- und Event-Modell völlig neu erfunden wird und das vorhandene Standard-DOM schwer und teuer ist und was auch immer, aber am Ende des Tages habe ich die Leistung von nicht gefunden Reagiere, um besser zu sein als das, was ich aus einer gut geschriebenen Backbone- oder Polymer-Anwendung herausholen kann. Tatsächlich war die Leistung von React in den meisten meiner beruflichen Erfahrungen etwas schlechter. Das heißt nicht, dass die Reaktion langsam ist ... Es ist einfach nicht die beste Wahl für die Performance, die wir alle dachten, bevor wir sie in den Griff bekommen haben.

In der Antwort von rsp weist er darauf hin, dass Reacts DOM-Modell für einen Div viel leichter ist als das native DOM-Div, und das ist sicherlich wahr. Damit React jedoch nützlich ist, muss diese "virtuelle" Div irgendwann eine echte Div werden. Meiner Weltanschauung nach handelt es sich also nicht um ein React Div gegen ein native Div. Es ist ein React Div + ein native Div vs nur ein native Div. Der Overhead der React-Version des DOM ist nicht trivial, und wenn die Standards jemals einige dieser nicht benötigten Attribute verwerfen und es den nativen DOM-Knoten ermöglichen, viel leichter zu werden, wird dieser Overhead plötzlich sehr teuer.

An einem meiner früheren Arbeitsorte hatten wir einige Bewerbungen in Polymer und einige Bewerbungen in React. Eine der frühen Polymer-Anwendungen wurde schließlich in React umgeschrieben, da dies der Standard des Unternehmens war. Basierend auf den Messungen nahm ich die React-Version derselben Anwendung, die mit etwa 30% mehr Speicher als die Polymer-Version aufgewickelt wurde und obwohl der Unterschied gering war, wurde die Polymer-Version auch in kürzerer Zeit gerendert. Hierbei ist zu berücksichtigen, dass es sich um Anwendungen handelt, die von Menschen geschrieben wurden, und die Menschen nicht perfekt sind. Es ist daher möglich, dass die React-Implementierung dieser Anwendung nicht alle Funktionen von React ausnutzt. Aber ich denke, zumindest ein Teil davon hat mit dem Overhead zu tun, den React durch eine eigene Version des DOM verursacht.

React erfindet das gesamte DOM mithilfe seines eigenen Modells neu und verwendet es dann für eine umfassende Leistungsoptimierung. Eine Ansicht wird in ein virtuelles DOM gerendert und dieses wird in das reale DOM projiziert. Wenn eine Änderung vorliegt und die Ansicht aktualisiert werden muss, wird die Ansicht erneut in ein virtuelles DOM gerendert, und dieser Baum wird gegenüber dem vorherigen Baum geändert, um zu bestimmen, welche Knoten im realen DOM geändert werden müssen, um diese Änderung widerzuspiegeln in der Ansicht. Dies ist zwar ein sehr geschickter Ansatz, um effiziente DOM-Aktualisierungen durchzuführen, es ist jedoch mit einem Mehraufwand verbunden, alle diese virtuellen DOM-Bäume zu verwalten und zu unterscheiden, um zu bestimmen, was im realen DOM geändert werden soll. Gegenwärtig wird dieser Mehraufwand durch die Leistungsvorteile stark ausgeglichen, aber wenn das native DOM im Laufe der Zeit verbessert wird, verschiebt sich die Skalierung in die andere Richtung. Ich mache mir Sorgen darüber, wie React Apps altern könnten. und wenn sie in 3 Jahren viel langsamer sind als Dinge, die sich direkter mit dem DOM befassen. Dieser virtuelle DOM-Ansatz ist ein bisschen wie ein Vorschlaghammer, und andere Bibliotheken wie Polymer konnten sehr effiziente Ansätze für den subtileren Umgang mit dem DOM implementieren.

Leistungsaktualisierung: Eine der Bibliotheken, über die ich vor einiger Zeit gestolpert bin, erledigt die Aktualisierung des DOM meiner Meinung nach besser. Es handelt sich um die inkrementelle Dom-Bibliothek von Google, und ich denke, dass die Tatsache, dass sie mit dem vorhandenen Dom zusammenarbeitet und keine "virtuelle Kopie" erstellen muss, einen viel saubereren Ansatz mit viel weniger Speicheraufwand darstellt. Weitere Informationen finden Sie hier: http://google.github.io/incremental-dom/#about

Deklarative vs imperative Komponenten

Eines der Dinge, die Sie immer hören, wenn Sie über das Komponieren Ihrer Anwendung sprechen, sind alle Vorteile, die sich aus der Deklaration Ihrer Komponenten ergeben. In Reacts Weltbild ist alles schön und aussagekräftig. Sie schreiben JavaScript, das Markup zurückgibt, und React klebt alles für Sie zusammen. Und das ist großartig, wenn Sie es mit einer brandneuen Anwendung zu tun haben, die nur React und sonst nichts verwendet. Sie können eine Komponente schreiben. Solange Sie sich in einem Teil des DOM befinden, dessen Eigentümer React ist, müssen Sie lediglich dieses Tag auf der Seite platzieren, um Ihre Komponente zu konsumieren.

Aber sobald Sie diese Komponenten nehmen und sie außerhalb von React verwenden, wird es sehr viel unordentlicher. Da die Art und Weise, in der React-Komponenten zu Tags verarbeitet werden, völlig außerhalb der von Webstandards bereitgestellten Möglichkeiten liegt, kann Ihnen nur React eine deklarative Methode zum Konsumieren dieser Komponenten bieten. Wenn ich React-Komponenten in eine vorhandene Backbone-Ansicht einfügen möchte, in der Handlebars-Vorlagen verwendet werden, müssen Sie ein Dummy-Div in Ihrer Vorlage mit einer Klasse oder ID rendern, die Sie als Handle verwenden können, und anschließend JavaScript schreiben, um dieses Dummy-Div zu finden und zu mounten Ihre Komponente hinein. Haben Sie eine Express.js-Anwendung, die serverseitige Vorlagen verwendet? Nun, es ist das gleiche Lied und der gleiche Tanz. Eine JSP-Seite? Sie lachen, aber es gibt eine Menge Anwendungen, die sie noch verwenden. Es sei denn, Sie sind eine Art Startup ohne vorhandenen Code. Sie müssen einige Klempnerarbeiten schreiben, um Ihre React-Komponenten in vielen Anwendungen wiederzuverwenden. In der Zwischenzeit erzielt Polymer Komponenten über den Web Components-Standard, und mithilfe der Custom Element-Spezifikation kann Polymer Komponenten erstellen, die der Browser nur nativ zu nutzen weiß. Ich kann eine Polymer-Komponente in eine JSP-Seite, eine Express.js-Vorlage, eine ASP.NET-Ansicht, eine Backbone-Ansicht ... sogar in eine React-Komponente einfügen. Buchstäblich überall, wo Sie HTML verwenden können, können Sie eine Polymer-Komponente verwenden. Leute, die für die Wiederverwendung konstruiert sind, setzen auf Webstandards, weil Standards der Vertrag sind, der es einfach macht, Dinge miteinander kompatibel zu machen. YouTube erstellt immer mehr Inhalte in Polymer (Quelle: Polymer erzielt Komponenten über den Web Components-Standard. Mithilfe der Custom Element-Spezifikation kann Polymer Komponenten erstellen, die der Browser nur von Haus aus zu verwenden weiß. Ich kann eine Polymer-Komponente in eine JSP-Seite, eine Express.js-Vorlage, eine ASP.NET-Ansicht, eine Backbone-Ansicht ... sogar in eine React-Komponente einfügen. Buchstäblich überall, wo Sie HTML verwenden können, können Sie eine Polymer-Komponente verwenden. Leute, die für die Wiederverwendung konstruiert sind, setzen auf Webstandards, weil Standards der Vertrag sind, der es einfach macht, Dinge miteinander kompatibel zu machen. YouTube erstellt immer mehr Inhalte in Polymer (Quelle: Polymer erzielt Komponenten über den Web Components-Standard. Mithilfe der Custom Element-Spezifikation kann Polymer Komponenten erstellen, die der Browser nur von Haus aus zu verwenden weiß. Ich kann eine Polymer-Komponente in eine JSP-Seite, eine Express.js-Vorlage, eine ASP.NET-Ansicht, eine Backbone-Ansicht ... sogar in eine React-Komponente einfügen. Buchstäblich überall, wo Sie HTML verwenden können, können Sie eine Polymer-Komponente verwenden. Leute, die für die Wiederverwendung konstruiert sind, setzen auf Webstandards, weil Standards der Vertrag sind, der es einfach macht, Dinge miteinander kompatibel zu machen. YouTube erstellt immer mehr Inhalte in Polymer (Quelle: Ich kann eine Polymer-Komponente in eine JSP-Seite, eine Express.js-Vorlage, eine ASP.NET-Ansicht, eine Backbone-Ansicht ... sogar in eine React-Komponente einfügen. Buchstäblich überall, wo Sie HTML verwenden können, können Sie eine Polymer-Komponente verwenden. Leute, die für die Wiederverwendung konstruiert sind, setzen auf Webstandards, weil Standards der Vertrag sind, der es einfach macht, Dinge miteinander kompatibel zu machen. YouTube erstellt immer mehr Inhalte in Polymer (Quelle: Ich kann eine Polymer-Komponente in eine JSP-Seite, eine Express.js-Vorlage, eine ASP.NET-Ansicht, eine Backbone-Ansicht ... sogar in eine React-Komponente einfügen. Buchstäblich überall, wo Sie HTML verwenden können, können Sie eine Polymer-Komponente verwenden. Leute, die für die Wiederverwendung konstruiert sind, setzen auf Webstandards, weil Standards der Vertrag sind, der es einfach macht, Dinge miteinander kompatibel zu machen. YouTube erstellt immer mehr Inhalte in Polymer (Quelle:http://react-etc.net/entry/youtube-is-being-rebuilt-on-web-components-and-polymer ), und ich kann mir nur vorstellen, warum der standardbasierte Aspekt von Polymer der Grund ist. Dieser YouTube-Player in der Mitte der YouTube-Seite könnte in eine Komponente umgewandelt werden, die eine Inhaltsquelle als Eigenschaft aufnimmt, und plötzlich kann jeder, der den YouTube-Player in seine Seite einbetten möchte, genau denselben Player-Code verwenden, den YouTube verwendet und sie können dies einfach tun, indem sie ein Tag in ihre Seite stecken.

Zusammenfassung

Ich kann jetzt definitiv einige ansprechende Aspekte von React erkennen. Wenn Sie nur React verwenden, können Sie einige Widgets und einige Komponenten erstellen und sie überall deklarativ wiederverwenden. Aber ich denke, React wäre viel besser dran gewesen, wenn es einige der Web Components-Standards verwendet hätte, um das zu erreichen, was es tut, anstatt einen Browser innerhalb eines Browsers und einen komplexen Mechanismus aufzubauen, um alles synchron zu halten.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.