Vergleich von JS-Frameworks: React, Vue und Hyperapp

Der Autor des Materials, dessen Übersetzung wir heute veröffentlichen, ist der Ansicht, dass Hyperapp eine bemerkenswerte Alternative zu Web-Frameworks wie React oder Vue darstellt . Der Grund für diese Behauptung sei, dass er herausgefunden habe, dass Hyperapp leichter zu erlernen sei als die beiden Frameworks. Seine Idee wurde kritisiert, weil sie anscheinend ausschließlich auf seiner Meinung beruht und dieser Ansatz anderen Frameworks einfach nicht die Möglichkeit gibt, ihre Stärken zu zeigen. Dieser Artikel zielt auf eine objektive Analyse von Hyperapp, React und Vue ab, basierend auf einfachen Beispielen, die ihre Fähigkeiten und auf der Grundlage ihrer Testergebnisse demonstrieren.



Beispiel 1: Zähleranwendung


Die Implementierung der Zähleranwendung ist wahrscheinlich eines der am häufigsten verwendeten Beispiele in der reaktiven Programmierung. Es ist sehr einfach und verständlich:

  • Wir brauchen die Variablenanzahl, die den Wert des Zählers speichert.
  • Es werden zwei Methoden benötigt, um die count der Variablen zu erhöhen und zu verringern.
  • Ein Mechanismus ist erforderlich, um den in count gespeicherten Wert anzuzeigen und dem Benutzer anzuzeigen.
  • Es werden zwei Schaltflächen benötigt, die an die entsprechenden Methoden gebunden sind, sodass der Benutzer auf die count reagieren kann.

Hier ist eine Implementierung dieses Beispiels unter Verwendung der fraglichen Frameworks.

▍Reakt


 import React from "react"; import ReactDOM from "react-dom"; Class Counter extends React.Component {   constructor(props) {       super(props);       this.state = { count: 0};   }   down(value) {       this.setState(state => ({ count: state.count - value }));   }   up(value) {       this.setState(state => ({ count: state.count + value }));   }   render() {       return (           <div>               <h1>{this.state.count}</h1>               <button onClick = {() => this.down(1)}>-</button>               <button onClick = {() => this.up(1)}>+</button>           </div>       );   } } ReactDOM.render(<Counter />, document.querySelector("#app")); 

UeVue


 import Vue from "vue"; new Vue({   data: { count: 0 },   methods: {       down: function(value) {           this.count -= value;       },       up: function(value) {           this.count += value;       }   },   render: function(h) {       return(           <div>               <h1>{this.count}</h1>               <button onClick={() => this.down(1)}>-</button>               <button onClick={() => this.up(1)}>+</button>           </div>       );   },   el: "#app" }); 

YHyperapp


 import { h, app } from "hyperapp"; const state = {   count: 0 }; const actions = {   down: value => state => ({ count: state.count - value}),   up: value => state => ({ count: state.count + value}) }; const view = (state, actions) => (   <div>       <h1>{state.count}</h1>       <button onclick={() => actions.down(1)}>-</button>       <button onclick={() => actions.up(1)}>+</button>   </div> ); app(state, actions, view, document.querySelector("#app")); 

▍Analyse


Wenn Sie mit diesen Frameworks oder sogar mit mindestens einem von ihnen nicht vertraut sind, werden Sie hier wahrscheinlich auf etwas Unverständliches treffen. Analysieren wir also diesen Code.

  • Bei Verwendung aller drei Frameworks befinden sich am Anfang des Anwendungscodes import .
  • React verwendet ein objektorientiertes Paradigma. Dadurch wird eine Klasse für die Counter Komponente erstellt. Vue geht den gleichen Weg. Hier wird eine neue Instanz der Vue Klasse erstellt, an die Informationen übergeben werden. Und schließlich verwendet Hyperapp ein funktionales Paradigma, es verwendet die view , den state und die actions unabhängiger Entitäten.
  • Wenn wir über die Variablenanzahl sprechen, wird sie in React im Komponentenkonstruktor initialisiert, und in Vue und Hyperapp ist sie eine Eigenschaft der data bzw. Statusobjekte.
  • Wenn wir uns weiter mit diesen Anwendungen befassen, können wir sehen, dass React und Vue sehr ähnliche Methoden verwenden, um mit der count zu interagieren. In React wird zum Ändern des Status einer Anwendung die von setState geerbte setState Methode React.Component . In Vue wird der Wert von this.count direkt geändert. Hyperapp-Methoden werden mit der ES6-Pfeilfunktionssyntax geschrieben. Unter den fraglichen Frameworks ist er der einzige, der dies verwendet, da React und Vue gezwungen sind, das Schlüsselwort this in ihren Methoden zu verwenden. Hyperapp-Methoden erfordern andererseits, dass ihnen als Argument ein Objekt mit Anwendungsstatus übergeben wird. Dies bedeutet, dass sie höchstwahrscheinlich in verschiedenen Kontexten wiederverwendbar sind.
  • Der Teil der Anwendung, der für die Ausgabe von Daten auf der Seite verantwortlich ist, sieht in allen drei Beispielen fast gleich aus. Die Besonderheit von Vue ist, dass bei Verwendung dieses Frameworks die h Funktion an das Rendering-Subsystem übergeben werden muss. Hyperapp verwendet onclick anstelle von onclick . Hier wird auf die count anders zugegriffen als auf React und Vue, da der Anwendungsstatus in den einzelnen Frameworks besonders gespeichert ist.
  • Und schließlich verwenden alle drei Frameworks die Bindung an das Element #app . In jedem von ihnen wird diese Operation unterschiedlich ausgeführt. Es sollte beachtet werden, dass diese Operation in Vue am einfachsten und verständlichsten aussieht und dem Entwickler ein flexibleres Design bietet, das mit der Elementauswahl und nicht mit dem Element selbst arbeitet.

▍ Schlussfolgerungen


Wenn Sie den Code direkt vergleichen, der das gleiche Problem löst, das mit allen drei Frameworks geschrieben wurde, stellt sich heraus, dass Hyperapp für die Implementierung der Zähleranwendung die geringste Anzahl von Codezeilen benötigt, und dies ist das einzige Framework, das einen funktionalen Ansatz verwendet. Wenn Sie jedoch die Anzahl der Zeichen zählen, die mit Vue geschrieben wurden, fällt die Anzahl der Zeichen etwas geringer aus, und die Verwendung eines Element-Selektors darin sieht sehr gut aus. Der Code der React-Anwendung scheint der längste zu sein, dies bedeutet jedoch nicht, dass er viel schwieriger zu verstehen ist als der Code, der für die Arbeit mit anderen analysierten Frameworks geschrieben wurde.

Beispiel Nr. 2: Arbeiten mit asynchronem Code


In der Praxis ist es möglich, dass Sie sich mit asynchronem Code befassen müssen. Eine der häufigsten asynchronen Operationen ist das Senden einer Anforderung an eine API. Für die Zwecke dieses Beispiels wird die JSONPlaceholder-API verwendet , die bedingte Daten enthält und Veröffentlichungen auflistet. Folgendes werden wir hier tun:

  • Wir speichern das Array für die Veröffentlichung im Anwendungsstatus.
  • Wir rufen mit der entsprechenden Methode fetch() , geben die benötigte URL an, warten auf das Eintreffen der Daten, analysieren den empfangenen JSON-Code, bei dem es sich um ein Array von Objekten handelt, und aktualisieren schließlich die Variable posts , indem wir die empfangenen Daten darauf schreiben.
  • Auf der Seite wird eine Schaltfläche angezeigt, die die Methode aufruft, mit der die Liste der Veröffentlichungen geladen wird.
  • Listen Sie die Beiträge von posts mit Schlüsseln auf.

Stellen Sie sich einen Code vor, der das obige Aktionsschema implementiert.

▍Reakt


 import React from "react"; import ReactDOM from "react-dom"; class PostViewer extends React.Component {   constructor(props) {       super(props);       this.state = { posts: [] };   }   getData() {       fetch(`https://jsonplaceholder.typicode.com/posts`)       .then(response => response.json())       .then(json => {           this.setState(state => ({ posts: json}));       });   }   render() {       return (           <div>               <button onClick={() => this.getData()}>Get posts</button>               {this.state.posts.map(post => (                   <div key={post.id}>                       <h2><font color="#3AC1EF">{post.title}</font></h2>                       <p>{post.body}</p>                   </div>               ))}           </div>       );   } } ReactDOM.render(<PostViewer />, document.querySelector("#app")); 

UeVue


 import Vue from "vue"; new Vue({   data: { posts: [] },   methods: {       getData: function(value) {           fetch(`https://jsonplaceholder.typicode.com/posts`)           .then(response => response.json())           .then(json => {               this.posts = json;           });       }   },   render: function(h) {       return (           <div>               <button onClick={() => this.getData()}>Get posts</button>               {this.posts.map(post => (                   <div key={post.id}>                       <h2><font color="#3AC1EF">{post.title}</font></h2>                       <p>{post.body}</p>                   </div>               ))}           </div>       );   },   el: "#app" }); 

YHyperapp


 import { h, app } from "hyperapp"; const state = {   posts: [] }; const actions = {   getData: () => (state, actions) => {       fetch(`https://jsonplaceholder.typicode.com/posts`)       .then(response => response.json())       .then(json => {           actions.getDataComplete(json);       });   },   getDataComplete: data => state => ({ posts: data }) }; const view = (state, actions) => (   <div>       <button onclick={() => actions.getData()}>Get posts</button>       {state.posts.map(post => (           <div key={post.id}>               <h2><font color="#3AC1EF">{post.title}</font></h2>               <p>{post.body}</p>           </div>       ))}   </div> ); app(state, actions, view, document.querySelector("#app")); 

▍Analyse


Lassen Sie uns diesen Code analysieren und die drei untersuchten Frameworks vergleichen.

  • Wie im vorherigen Beispiel sind das Speichern des Anwendungsstatus, das Ausgeben von Daten und das Herstellen einer Verbindung zum Seitenelement in allen drei Frameworks sehr ähnlich. Hier werden die gleichen Unterschiede beobachtet, die wir oben bereits erwähnt haben.
  • Das Herunterladen von Daten mit der Funktion fetch() ist recht einfach und funktioniert in allen Frameworks wie erwartet. Der Hauptunterschied besteht jedoch darin, dass Hyperapp asynchrone Vorgänge etwas anders unterstützt als andere Frameworks. Anstatt den Status direkt innerhalb einer asynchronen Aktion zu ändern, ruft diese Aktion eine andere synchrone Aktion auf, die die Daten empfängt und in ein geeignetes Format konvertiert. Dies macht den Anwendungskern funktionaler und besser geeignet, um in kleine Teile zu zerlegen, die möglicherweise zur Wiederverwendung geeignet sind. Dieser Ansatz hilft außerdem, einige der Probleme zu vermeiden, die verschachtelten Rückrufen inhärent sind und in solchen Situationen auftreten können.
  • Wenn wir über die Größe des Codes sprechen, benötigt die Hyperapp-Anwendung erneut weniger Codezeilen, um dasselbe Ziel zu erreichen. Der Vue-Code sieht jedoch kürzer aus. Wenn Sie die Anzahl der Zeichen im Code zählen, ist er kürzer als andere Optionen.

▍ Schlussfolgerungen


Das Ausführen asynchroner Operationen erwies sich in allen Frameworks als gleich einfach. Hyperapp kann den Entwickler dazu veranlassen, bei der Arbeit mit asynchronen Aktionen mehr funktionalen und modularen Code zu schreiben, aber auch die beiden anderen Frameworks erfüllen ihre Aufgabe hervorragend und geben dem Entwickler in dieser Hinsicht die Möglichkeit, eine Auswahl zu treffen.

Beispiel 3: Listenelementkomponente für eine Aufgabenanwendung


To-Do-Anwendungen sind wahrscheinlich das bekannteste Beispiel für reaktive Programmierung. Anscheinend wurde etwas Ähnliches mit fast jedem vorhandenen Framework implementiert. Hier werden wir nicht die gesamte Anwendung implementieren. Konzentrieren wir uns stattdessen auf eine einfache zustandslose Komponente, um die Möglichkeiten der untersuchten Frameworks zur Erstellung kleiner Bausteine ​​von Webanwendungen zu untersuchen, die für die Wiederverwendung geeignet sind.

Betrachten Sie die Implementierung der Komponente unter Verwendung der untersuchten Frameworks. In diesem Beispiel werden wir jedoch die betrachteten Codeoptionen erweitern, indem wir eine React-Komponente betrachten, die in einem funktionalen Stil geschrieben ist.

▍React (Funktionsstil)


 function TodoItem(props) {   return (       <li class={props.done ? "done" : ""} onclick={() => props.toggle(props.id)}>           {props.value}       </li>   ); } 

▍Reakt


 class TodoItem extends React.Component {   render () {       return (           <li class={this.props.done ? "done" : ""} onclick={() => this.props.toggle(this.props.id)}>               {this.props.value}           </li>       );   } } 

UeVue


 var TodoItem = Vue.component("todoitem", {   props: ["id", "value", "done", "toggle"],   template:       '<li v-bind:class="{done : done}" v-on:click="toggle(id)">{{value}}</li>' }); 

YHyperapp


Bitte beachten Sie, dass Hyperapp auch einen funktionalen Stil verwendet.

 const TodoItem = ({ id, value, done, toggle }) = (   <li class={done ? "done" : ""} onclick={() => toggle(id)}>       {value}   </li> ); 

▍Analyse


  • Reagieren in Bezug auf die Verwendung von Codierungsmustern ist das flexibelste Framework. Es unterstützt funktionale Komponenten sowie Komponenten, die als Klassen konzipiert sind. Darüber hinaus unterstützt React in seiner Standardform auch Hyperapp-Komponenten.
  • Hyperapp unterstützt auch funktionale React-Komponenten. Dies bedeutet, dass bei der Arbeit mit Hyperapp und React viel Raum zum Experimentieren vorhanden ist.
  • Vue belegt in diesem Test den letzten Platz. Es hat eine ziemlich seltsame Syntax, die selbst für diejenigen, die mit React oder Hyperapp vertraut sind, auf Anhieb schwer zu verstehen ist.
  • Wenn wir über die Länge des Codes sprechen, haben alle Beispiele sehr ähnliche Größen. Das einzige, was hier bemerkt werden kann, ist, dass der Code auf React in einer der Optionen etwas umfangreicher war als in der anderen.

▍ Schlussfolgerungen


Es dauert einige Zeit, bis Sie sich an Vue gewöhnt haben, da sich die Vorlagen geringfügig von den Vorlagen der beiden anderen Frameworks unterscheiden. React ist äußerst flexibel und unterstützt verschiedene Ansätze zum Erstellen von Komponenten. Gleichzeitig ist in Hyperapp alles sehr einfach und es ist auch mit React kompatibel, sodass Sie das Framework bei Bedarf zu einem bestimmten Zeitpunkt des Projekts ändern können.

Vergleich der Methoden des Komponentenlebenszyklus


Eine weitere wichtige Überlegung, die sich auf die Auswahl eines Frameworks auswirkt, sind die von ihm unterstützten Komponentenlebenszyklusereignisse, die Sie abonnieren und entsprechend den Anforderungen des Entwicklers verarbeiten können. Hier ist eine Tabelle, die auf einer Analyse der API der untersuchten Systeme basiert.
Ereignis
Reagiere
Vue
Hyperapp
Initialisierung
Konstruktor
beforeCreate, erstellt
- -
Montage
comoinentDidMount
beforeMount, montiert
oncreate
Update
componentDidUpdate
beforeUpdate, aktualisiert
onupdate
Aussteigen
componentWillUnmount
- -onremove
Zerstörung
- -beforeDestroy, zerstört
ondestroy

▍Analyse


Folgendes können Sie anhand der Analyse dieser Tabelle verstehen:

  • Die meisten Lifecycle-Hooks befinden sich in Vue. Mit ihrer Hilfe hat der Programmierer die Möglichkeit, alles, was mit der Komponente geschieht, entweder vor oder nach dem Aufruf des entsprechenden Ereignisses zu verarbeiten. Dies kann nützlich sein, um komplexe Komponenten zu verwalten.
  • Die Lifecycle-Hooks von React und Hyperapp sind sehr ähnlich, obwohl React die Verarbeitung von Ereignissen kombiniert, die beim Aufheben und Zerstören einer Komponente auftreten, während Hyperapp auch auf Ereignisse beim Erstellen und Mounten einer Komponente reagiert. Beide bieten dem Entwickler eine ausreichende Anzahl von Möglichkeiten zur Verarbeitung von Lebenszyklusereignissen.
  • Vue behandelt das Unmount-Ereignis nicht (soweit Sie anhand der Analyse der Framework-API verstehen können), sondern stützt sich auf Hooks, die mit der Zerstörung der Komponente verbunden sind. React verarbeitet kein Komponenten-Kill-Ereignis, sodass nur ein Ereignis zum Aufheben der Bereitstellung von Komponenten verarbeitet werden kann. Hyperapp bietet keine Hooks für die Verarbeitung von Komponentenerstellungsereignissen an, sondern stützt sich ausschließlich auf Mount-Ereignisse. Abhängig von Ihren Anforderungen und Ihrer Erfahrung sollten diese Unterschiede beim Entwerfen einer Anwendung berücksichtigt werden, wobei die Möglichkeit der Verarbeitung von Komponentenlebenszyklusereignissen zu berücksichtigen ist.

▍ Schlussfolgerungen


Im Allgemeinen kann festgestellt werden, dass Methoden zur Behandlung von Ereignissen, die während des Lebenszyklus von Komponenten auftreten, alle Frameworks unterstützen. Diese Methoden lösen viele Probleme. Alle drei Frameworks bieten Hooks für alle Arten von Ereignissen, es gibt jedoch geringfügige Unterschiede zwischen ihnen, deren Ursache die internen Merkmale der Frameworks und Unterschiede in ihrer Implementierung sein können. Vielleicht ist Vue in diesem Bereich anderen Systemen einen Schritt voraus und bietet ein detaillierteres Ereignisverarbeitungssystem, mit dem Sie Lebenszyklusereignisse entweder vor oder nach ihrem Auftreten verarbeiten können.

Vergleich der Framework-Leistung


Neben der Bequemlichkeit der Verwendung des Frameworks und der für die Arbeit verwendeten Programmiertechniken sind viele Entwickler ernsthaft besorgt über die Leistung von Frameworks, insbesondere für relativ komplexe Anwendungen. Eine wertvolle Informationsquelle über die Leistung verschiedener Frameworks ist das js-Framework-Benchmark- Projekt.

Schauen Sie sich daher die Testergebnisse von React, Vue und Hyperapp an.

▍Arbeiten mit Tischen


Hier sind die Testergebnisse der Frameworks für die Arbeit mit Tabellen. Der Indikator in den Zellen der Tabelle entspricht der Betriebsdauer ± Standardabweichung. Das Ergebnis der Division des erhaltenen Indikators durch den besten Indikator ist in Klammern angegeben.


Analyse


  • Operationen, bei denen Schlüssel (ohne Schlüssel) nicht für die Datenausgabe verwendet werden, sind viel schneller als Operationen, bei denen Schlüssel (mit Schlüssel) verwendet werden.
  • Die schnellste aller sechs in Betracht gezogenen Optionen war die, bei der React ohne Verwendung von Schlüsseln verwendet wird, was bei allen Tests eine beeindruckende Leistung zeigt.
  • Wenn Sie Vue und React vergleichen, wenn Sie mit Schlüsseln arbeiten, hat Vue einen kleinen Vorteil. Wenn Sie React und Vue in Varianten vergleichen, in denen keine Schlüssel verwendet werden, zeigt Vue gleichzeitig eine deutlich geringere Leistung als React.
  • Wie Sie den Ergebnissen entnehmen können, haben Vue und Hyperapp einige Schwierigkeiten mit dem Test, bei dem die teilweise Aktualisierung der Tabelle durchgeführt wird, und React zeigt sich gut darin, wahrscheinlich aufgrund einer Optimierung, die darauf abzielt, diese zu beschleunigen Operationen.

▍Laden, Starten, Codegrößen


Hier ist eine Tabelle mit den Ergebnissen einer Studie von Indikatoren, die sich auf die Geschwindigkeit des Starts des Frameworks, auf seine Größe und auf die Verwendung des Hauptthreads beziehen.


Analyse


  • Hyperapp-Code erwies sich als der kleinste unter den untersuchten Frameworks. React- und Vue-Code sind ungefähr gleich groß.
  • Hyperapp benötigt am wenigsten Zeit zum Starten. Der Grund dafür ist natürlich die geringe Größe des Framework-Codes und der minimalistische Ansatz beim Entwerfen seiner API.
  • Wenn es um die Zeit geht, die zum Starten des Frameworks benötigt wird, ist Vue etwas schneller als React.

▍Arbeiten mit Speicher


Betrachten Sie nun die Ergebnisse des Testens der Speicherzuordnung.


Analyse


  • Hyperapp ist das anspruchsloseste Framework in Bezug auf den Speicherverbrauch.
  • Im Allgemeinen kann festgestellt werden, dass alle Frameworks nicht viel Speicher belegen. Dies deutet darauf hin, dass sie auf modernen Computern ungefähr gleich funktionieren.

▍ Schlussfolgerungen


Wenn Sie bei der Entwicklung eines Projekts maximale Leistung erzielen müssen, sollten Sie erstens verstehen, welche Art von Anwendung Sie entwickeln, und zweitens, um die Anforderungen dieser Anwendung klar zu bestimmen. Wenn Sie die Leistungsanalyse aller drei Frameworks kombinieren, haben Sie das Gefühl, dass Vue und React besser für komplexere Anwendungen geeignet sind, und Hyperapp ist besser für kleinere Anwendungen geeignet, die weniger Daten verarbeiten müssen und deren Ausführung so schnell wie möglich ist. und wer muss möglicherweise nicht auf den schnellsten Computern arbeiten.

Es sei jedoch daran erinnert, dass die hier verwendeten Leistungstests weit vom wirklichen Leben entfernt sind, von einer Art gemitteltem Szenario. Wenn Sie sie an einem realen Projekt getestet und verglichen haben, können Sie daher andere Ergebnisse sehen.

Zusätzliche Hinweise


Es sollte beachtet werden, dass der Vergleich von Web-Frameworks dem Vergleich von Äpfeln mit Orangen ähneln kann. Im Folgenden finden Sie einige weitere Überlegungen zu React, Vue und Hyperapp, die bei der Auswahl eines bestimmten Frameworks für ein Projekt hilfreich sein können:

  • React umgeht das Problem, dass benachbarte JSX-Elemente in das übergeordnete Element eingeschlossen werden müssen, und führt das Konzept der Fragmente ein - Elemente, mit denen Sie eine Reihe von untergeordneten Elementen gruppieren können, ohne dem DOM zusätzliche Knoten hinzuzufügen.
  • React stellt dem Entwickler Komponenten höherer Ordnung zur Verfügung , während Vue Mixins verwendet , um die Komponentenfunktionalität wiederzuverwenden.
  • Vue nutzt das Konzept der Aufgabentrennung vollständiger und trennt die Struktur und Funktionalität der Anwendung mithilfe von Vorlagen .
  • Hyperapp sieht im Vergleich zu React und Vue wie ein System aus, das eine API auf niedrigerer Ebene bietet. Der Code von Hyperapp-Anwendungen ist kürzer und bietet große Flexibilität. Dies kann hilfreich sein, wenn der Entwickler ihn möglicherweise durch Feinabstimmung und Erforschung seiner internen Mechanismen angehen möchte.

Zusammenfassung


Der Autor dieses Materials ist der Ansicht, dass Sie, wenn Sie bis zu diesem Punkt lesen, bereits verstehen, welches der hier untersuchten Frameworks Ihren Anforderungen am besten entspricht. Am Ende haben wir nicht darüber gesprochen, welches der Frameworks das beste ist, sondern darüber, welches sich in verschiedenen Situationen am besten zeigen kann. Infolgedessen können wir die folgenden allgemeinen Schlussfolgerungen ziehen:

  • React — , , , - , . , , , , . , React — , .
  • Vue , - JavaScript-, — . React, , , , React - . Vue , , , , React.
  • , , Hyperapp — , , — . , React Vue, . , . , Hyperapp, , , , Hyperapp-, . , , Hyperapp, , , , React Vue, .

! -?


, - 10% :)

Source: https://habr.com/ru/post/de417483/


All Articles