Vue.js & React – JavaScript UI Frameworks im Vergleich

2 Kommentare

In meinem vorherigen Beitrag habe ich euch Vue.js vorgestellt. React und Vue.js sind zur Zeit die leuchtenden Sterne am JavaScript-UI-Himmel, mit riesigen, aktiven Communities, die sich natürlich intensiv mit den Vor- und Nachteilen auseinandersetzen. Doch was macht mehr Spaß, als sich nur darüber zu unterhalten? Genau, sich im Code verwirklichen und das Ganze in einem Vergleich zwischen unseren beiden Frameworks.

Dann lasst uns herausfinden, welches Framework rockt. Ich habe zwei ähnliche Applikationen geschrieben, jeweils in Vue.js und in React. Checkt das Repo aus und schaut euch den Code an, auf den wir im weiteren Verlauf eingehen werden.

Battleship Applikation in React                                Battleship Applikation in Vue.js

Die Kontrahenten

Selbst wenn ihr euch in den letzten Jahren unter einem Stein versteckt haben solltet, ist das von Facebook entwickelte JavaScript UI Framework React nicht ohne Spuren an euch vorbei gegangen. Es befeuert viele der von Facebook betriebenen Applikationen, wie zum Beispiel Instagram, als eine der bekanntesten Plattformen, und natürlich die Facebook-Seite selbst. Als React veröffentlicht wurde, ging es wie ein Raunen durch die Massen. Es war ein grundlegend neuer Ansatz, im Vergleich zu den damaligen Platzhirschen jQuery, Backbone.js und Angular 1.

Der größte Unterschied bei React, im Vergleich zu den vorher genannten Frameworks, besteht in der Einführung des virtual DOMs und einer neuen Syntax namens JSX, die es Entwicklern ermöglicht, HTML in JavaScript einzubetten.

Vue.js ist sehr stark an React angelehnt und versucht die gleichen Probleme zu lösen, aber auf eine andere Art und Weise. Es nutzt ein vereinfachtes Templating System und macht die Integration in bestehende Apps einfacher, da das Templating stark auf die etablierte HTML-Syntax und -Semantik aufbaut. Der Einstieg wird durch die Nähe zu normalem HTML/CSS und JavaScript stark vereinfacht.

Gemeinsamkeiten

React und Vue.js haben eine Menge gemeinsam. Beide sind JavaScript UI Frameworks mit dem Ziel, robuste und performante Frontend-Applikationen zu entwickeln. Im Vergleich zu älteren Frameworks, die mit tonnenweise Zusatzbibliotheken an Bord daher kamen, beschränken sich unsere Kontrahenten auf das wesentliche, funktionale Grundgerüst mit Routing und State Management. Diese werden bei Vue.js und React durch separat verwaltete Libraries zur Verfügung gestellt.

Das Mysterium virtual DOM

Was beide verbindet, ist die Implementierung des virtual DOM. Technisch gesehen ist es genau das, wonach es klingt: eine virtuelle Darstellung des DOM-Baums. Es entstand aus dem Verlangen heraus, die hochfrequenten, rechenintensiven Updates des echten DOMs zu vereinfachen, und die Aktualisierung eines JavaScript-Objektes ist relativ leichtgewichtig, wenn man beide miteinander vergleicht.

Nehmen wir mal als kleines Beispiel eine einfache HTML-Liste:

Als JavaScript-Objekt könnte diese Liste wie folgt aussehen:

Das ist natürlich ein sehr einfaches Beispiel. Die aktuellen Implementierungen des virtual DOMs sind wesentlich komplexer. Aber im Ansatz bestehen sie aus verschachtelten JavaScript-Objekten und Arrays.

Jetzt kommt die geheime Zutat für das virtual DOM, das so genannte Diffing”. Wird ein neues Element dem virtual DOM in Form eines JavaScript-Objektes hinzugefügt, startet eine Funktion und vergleicht die Änderungen in unserem Objekt und wendet diese dann auf das echte DOM an. Beide Frameworks handhaben dies jedoch unterschiedlich. Im direkten Vergleich spürt man den Performance-Unterschied. Vue.js ist in der Lage, Änderungen von Komponenten und deren Unterkomponenten zu überwachen und muss nicht den kompletten Komponentenbaum, inklusive deren Unterkomponenten, neu rendern.

React geht hier einen anderen Weg und rendert alle Komponenten und deren Unterkomponenten neu, sobald der Application State geändert wird. Dies kann man jedoch unterbinden, da es für einen Performance-Anstieg sorgt, wenn man die Lifecycle-Methode shouldComponentUpdate() nutzt.

Hinweis: Das virtual DOM zu nutzen, ist von enormem Vorteil beim Entwickeln von Applikationen, die häufig UI-Komponenten aktualisieren müssen. Werden UI-Elemente eher unregelmäßig aktualisiert, wäre die Implementierung für diesen Fall Overkill und kann im schlechtesten Fall langsamer sein, als mit dem echten DOM zu arbeiten.

Komponentenbasierte Architektur

Beide Frameworks nutzen die komponentenbasierte Architektur. Im Wesentlichen bedeutet dies eine Unterteilung der Applikation in mehrere kleine Teile, die funktional miteinander kommunizieren oder als eigenständige Module laufen können. Eine gute Erklärung dieses Patterns findet man in diesem Medium Artikel.

Eine Komponente kann man als kleinen Teil eines kompletten Userinterfaces betrachten. Am Beispiel von Facebook und dessen Social-Media-Plattform, könnte der Chat eine Komponente sein, und der Kommentar-Feed wäre eine weitere Komponente. Die stets aktuelle Freundesliste wäre eine weitere Komponente, und so formt sich aus mehreren Komponenten die Facebook-Welt.

In Vue.js nutzen wir Single File Components, diese kennen wir bereits aus dem ersten Artikel.

Im oberen Beispiel erkennen wir sehr gut die Kombination aus HTML, JavaScript und CSS, die eine Single File Component bilden.

In React ist der Aufbau ähnlich, jedoch verwenden wir nun die JSX-Syntax.

Properties

Anhand der oberen Beispiele erkennt man, dass beide Frameworks das Konzept der Properties, kurz props, nutzen. Sie sind spezielle Attribute, die es den Parent- und Child-Komponenten erlaubt, miteinander zu kommunizieren und Daten auszutauschen.

Im oberen Codeabschnitt auf JSX-Basis werden index, key, ship und isInFleet als props definiert und können diese an die Child-Komponente SingleShip übermitteln. Dieses Vorgehen ist wichtig in React, doch darauf gehe ich später ein, da es als single source of truth dient.

In Vue.js werden die props in der Komponente definiert und in die Elterninstanz übergeben. Hier kommt die, zugegeben etwas tricky anzuwendende, Template-Syntax zum Einsatz, und wir greifen auf die integrierte v-for loop-Funktion zurück.

Ich finde es besser lesbar als die React-Variante, dies ist aber auch Geschmacksache.

Build Tools

Die beiden Kontrahenten bringen Tools mit, die das Erstellen neuer Projekte sehr einfach von der Hand gehen lassen. React benutzt Create React App (CRA) und Vue.js nutzt das vue-cli. Die Tools erledigen das notwendige Scaffolding und das Projekt-Setup nach aktuellen Best-Practice-Standards.

CRA geht hier restriktiver vor und zwingt euch, prinzipiell Webpack und Babel zu nutzen. Insgesamt ist es aber ein sehr stabiles Tool, das macht, was es soll. Bei dem vue-cli hat man die Möglichkeit, auf verschiedene Templates (Progressive Web Apps, ServiceWorker, Graphql mit Apollo…)  zurückzugreifen, die einen flexibleren Projektstart ermöglichen.

Beide Tools sind sehr ausgereift und gestalten den Start neuer Projekte sehr leicht. Mühselige Webpack-Konfigurationen kann man sich also sparen, was im Arbeitsalltag sehr angenehm ist.

Chrome Devtools

Ein täglicher Begleiter sind die Devtools für Chrome, die beide Frameworks bereitstellen und die beim Debugging sehr hilfreich sind. Analog zu den bereits aus Chrome bekannten Devtools, ermöglichen diese jedoch das React oder Vue.js Markup, States und Events zu untersuchen.

React devtools in Aktion:

react-devtools-recording

Vue devtools in Aktion:

vue.js-devtools-recording

Companion Frameworks

Eine weitere Gemeinsamkeit zwischen den beiden Frameworks ist der Fokus auf den User-Interface-Bereich. Funktionalitäten, wie Routing oder State Management, werden in separate Frameworks ausgelagert. Der einzige Unterschied besteht hier in der Maintenance dieser Projekte. Das Vue.js Coreteam betreut die Frameworks vue-router und Vuex (State Management). React-router und React-Redux werden durch Community-Mitglieder verwaltet und somit nicht offiziell von Facebook oder dem React-Coreteam betreut.

Die wesentlichen Unterschiede

Templating vs. JSX

Der wohl größte Unterschied zwischen beiden ist die Schreibweise für Templates. Vue.js geht den Weg mit dem bekannten HTML-Aufbau und erweitert diesen mit weiteren Attributen (Direktiven bekannt aus Angular).

Diese Attribute kann man auch auf Ebene der Single File Components nutzen, jedoch wird hier ein Build-Prozess erforderlich, der diese Komponente in eine valide JavaScript- und HTML-Syntax umwandelt.

Vue.js bevorzugt HTML zum Rendern der Elemente und kombiniert dies mit der aus Angular bekannten Mustache-Syntax zur Ausgabe dynamischer Inhalte. Dieser Ansatz ermöglicht es, sehr schnell Vue-Komponenten in bestehende Projekte zu integrieren, da beim Refactoring weniger Arbeit am HTML notwendig ist. Ein weiterer Vorteil dieses Ansatzes ist der einfache Einstieg für Frontend-Entwickler, da sie aus diesem Bereich kommen und mit der HTML-Syntax sehr vertraut sind.

React bevorzugt es, alle Templates in JavaScript zu schreiben. Hierzu wird die Syntax-Extension to JavaScript (JSX) genutzt.

Hinweis: React setzt stark auf die ES6-Syntax und den entsprechenden neuen Methoden für die Objekt- und Array-Verarbeitung. Das obere Beispiel kann man auch in einem for of Loop darstellen. Jedoch muss dieser Loop in eine separate Funktion ausgelagert werden, da JSX for loops in der render()-Methode nicht zulässt.

Dieser Code sieht für Einsteiger unvertraut und fremd aus, doch durch den Einsatz von JavaScript in unseren Templates bekommen wir mehr Kontrolle über die Programmlogik und können auf alle JavaScript-Funktionen und -Methoden zurückgreifen. Bei sehr großen Applikationen kann dies ein sehr mächtiges Werkzeug sein.

But remember, with great power comes great responsibility. Ben Parker

JSX ist mit einer XML-Syntax kombiniert, fühlt sich im ersten Moment komisch an, doch wenn man einmal seine Komfortzone verlässt und sich damit vertraut gemacht hat, kann man damit sehr flexibel und robust arbeiten. Ein Argument für Vue.js an dieser Stelle ist die Template-Syntax. Die Syntax verhindert, dass man unnötige programmatische Logik in Komponenten einbaut und begünstigt somit den Ansatz Separation of Concerns”. Erwähnenswert ist auch, dass Vue.js die aus React bekannten Render functions unterstützt und auch JSX zulässt, aber es ist nicht der Best-Practice-Weg, um mit Vue.js zu entwickeln.

State management vs. object properties

Ist man bereits mit React vertraut, ist das Application-State-Konzept nichts Neues. In diesem Kontext müssen wir Redux erwähnen, da es perfekt geeignet ist, um große Applikationen mit dem dazugehörigen State Management zu unterstützen. React setzt voraus, dass Daten im lokalen State immutable sind. Dies bedeutet, man kann diese nicht direkt verändern und muss auf die setState()-Methode zurückgreifen.

Vue.js benötigt kein lokales State-Objekt, und Daten werden über die data-Eigenschaft des Vue.js-Objektes verwaltet.

Man sieht im oberen Beispiel, dass wir keine Funktion wie setState()  aufrufen müssen. Der data()-Parameter des Vue.js-Objektes dient als Platzhalter für die Daten der Applikation.

Hinweis: Für kleinere Anwendungen kann man diesen Ansatz nutzen, doch bei größeren Projekten sollte man stets auf die dedizierten Lösungen Redux und Vuex zurückgreifen. Ein lokales State-Management als single source of truth ist bei großen Anwendungen von enormen Vorteil und macht das Debugging wesentlich einfacher und nachvollziehbarer.

React Native vs. ?

Im Bereich der Native Mobile Applications hat React mit React Native einen enormen Vorteil und eine sehr ausgereifte Lösung für das Entwickeln dieser Anwendungen. Die Vue.js Community arbeitet, zusammen mit dem E-Commerce-Schwergewicht Alibaba Group, an einer ähnlichen Lösung namens Weex. Sie befindet sich aber noch in der Entwicklung und ist noch nicht so ausgereift wie die Alternative aus dem Hause Facebook.

Zusammenfassung

Wenn ihr auf der Suche nach einem performanten und leistungsstarken JavaScript UI Framework seid, sind Vue.js und React definitiv eine Empfehlung. React hat hier gefühlt, auch aufgrund der größeren Community und Verbreitung, die Nase vorn, doch Vue.js ist ein würdiger Kontrahent. Möchtet ihr ein JavaScript Framework in eine existierende Anwendung integrieren, werft einen Blick auf Vue.js. Sollte man vor der Entwicklung einer größeren App stehen und will nicht auf die native, mobile Variante verzichten, ist React zum aktuellen Zeitpunkt der Gewinner. Jedoch kommt es natürlich immer auf die Probleme an, die es zu lösen gilt, und hier glänzen beide Frameworks mit verschiedenen Ansätzen, die es manchmal einfacher oder etwas komplizierter machen, dieses Problem zu lösen. Wie heißt es bei uns in der IT immer so schön… It depends.

Wie sind eure Erfahrungen und Gedanken in Bezug auf die beiden Frameworks Vue.js und React? Lasst uns darüber in den Kommentaren reden.

Toni Haupt

Toni arbeitet seit Mai 2017 bei der codecentric als Lead UI Consultant. Seine Schwerpunktthemen sind die Erstellung moderner Frontend Applikation mit einem starken Fokus auf UI und Usability. Dabei spielen Rapid Prototyping nach Atomic Design Prinzipien eine große Rolle. Eine weitere Leidenschaft ist die Rolle als Core Entwicker im WordPress Umfeld.

Kommentare

  • Name

    Sehr coole Zusammenfassung!

    Was mir an den Templates für Angular und Vue nicht gefällt, ist dass die Logik sowohl im Template als auch im Model implementiert sein muss.

    Ist das 2-way-databinding in Vui so gelöst wie in Angluar?

    • Gregor Elke

      In Vue gibt es kein 2-way-databinding. Genau so wie React erzwingt Vue einen One-Way Dataflow. Die Probleme, die 2-wege Databinding lösen soll (DOM-rerendering performant halten) wird in React und Vue durch Virtual-DOM, Diffing und partielles re-rendering gelöst.

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.