Comparaison des frameworks JS: React, Vue et Hyperapp

L'auteur du matériel, dont nous publions la traduction aujourd'hui, pense qu'Hyperapp est une alternative notable aux frameworks Web tels que React ou Vue . Il dit que la raison de cette affirmation est qu'il a découvert que Hyperapp était plus facile à apprendre que les deux cadres. Son idée a été critiquée, car il semble qu'elle repose uniquement sur son opinion, et cette approche ne donne tout simplement pas aux autres cadres la possibilité de montrer leurs points forts. Cet article vise une analyse objective d'Hyperapp, React et Vue, basée sur des exemples simples qui démontrent leurs capacités, et sur la base des résultats de leurs tests.



Exemple # 1: contre-application


L'implémentation de la contre-application est probablement l'un des exemples les plus couramment utilisés en programmation réactive. C'est extrêmement simple et compréhensible:

  • Nous avons besoin du count variable, qui stockera la valeur du compteur.
  • Deux mĂ©thodes seront nĂ©cessaires pour incrĂ©menter et dĂ©crĂ©menter le count variables.
  • Un mĂ©canisme est nĂ©cessaire pour afficher la valeur stockĂ©e dans count et la prĂ©senter Ă  l'utilisateur.
  • Deux boutons sont nĂ©cessaires qui sont liĂ©s aux mĂ©thodes appropriĂ©es, permettant Ă  l'utilisateur d'agir sur la variable de count .

Voici une implémentation de cet exemple utilisant les frameworks en question.

▍ Réagir


 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")); 

â–ŤVue


 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" }); 

â–ŤHyperapp


 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


Si vous n'êtes pas familier avec ces cadres, ou même avec au moins l'un d'entre eux, alors ici, vous rencontrerez probablement quelque chose d'incompréhensible. Analysons donc ce code.

  • Lorsque vous utilisez les trois cadres, il existe import commandes d' import au dĂ©but du code d'application.
  • React utilise un paradigme orientĂ© objet. Cela crĂ©e une classe pour le composant Counter . Vue va de la mĂŞme façon. Ici, une nouvelle instance de la classe Vue est créée, des informations lui sont transmises. Et enfin, Hyperapp utilise un paradigme fonctionnel, il utilise la view , l' state et les actions des entitĂ©s indĂ©pendantes.
  • Si nous parlons du count variables, alors dans React, il est initialisĂ© dans le constructeur du composant, et dans Vue et Hyperapp, c'est une propriĂ©tĂ© des data et state objets d' state , respectivement.
  • Si nous allons plus loin dans l'exploration de ces applications, nous pouvons voir que React et Vue utilisent des mĂ©thodes très similaires pour interagir avec la variable count . Dans React, pour modifier l'Ă©tat d'une application, la mĂ©thode setState hĂ©ritĂ©e de React.Component . Dans Vue, la valeur de this.count modifiĂ©e directement. Les mĂ©thodes Hyperapp sont Ă©crites Ă  l'aide de la syntaxe de la fonction de flèche ES6. Parmi les frameworks en question, il est le seul Ă  l'utiliser, puisque React et Vue sont obligĂ©s d'utiliser le mot this clĂ© this dans leurs mĂ©thodes. Les mĂ©thodes Hyperapp, en revanche, nĂ©cessitent de leur transmettre, en tant qu'argument, un objet avec l'Ă©tat d'application. Cela signifie qu'ils sont plus susceptibles d'ĂŞtre rĂ©utilisables dans divers contextes.
  • La partie de l'application responsable de la sortie des donnĂ©es sur la page est presque identique dans les trois exemples. La particularitĂ© de Vue est que lors de l'utilisation de ce framework, la fonction h doit ĂŞtre passĂ©e au sous-système de rendu. Hyperapp utilise onclick au lieu d' onclick , et ici, la variable count est accessible diffĂ©remment de React et Vue, en raison des particularitĂ©s de la façon dont l'Ă©tat de l'application est stockĂ© dans chaque framework.
  • Et enfin, les trois frameworks utilisent la liaison Ă  l'Ă©lĂ©ment #app . Dans chacun d'eux, cette opĂ©ration est effectuĂ©e diffĂ©remment. Il convient de noter que dans Vue, cette opĂ©ration semble la plus simple et la plus comprĂ©hensible et donne au dĂ©veloppeur une conception plus flexible, travaillant avec le sĂ©lecteur d'Ă©lĂ©ment et non avec l'Ă©lĂ©ment lui-mĂŞme.

â–Ť Conclusions


Si vous comparez directement le code qui résout le même problème écrit à l'aide des trois cadres, il s'avère que Hyperapp, pour la mise en œuvre de l'application de compteur, nécessite le moins de lignes de code, et c'est le seul cadre qui utilise une approche fonctionnelle. Cependant, la quantité de code écrit à l'aide de Vue, si vous comptez le nombre de caractères, il s'avère un peu moins, et l'utilisation d'un sélecteur d'élément semble très bonne. Le code de l'application React semble être le plus long, mais cela ne signifie pas qu'il est beaucoup plus difficile à comprendre que le code écrit pour travailler avec d'autres frameworks analysés.

Exemple n ° 2: travailler avec du code asynchrone


Il est possible que, dans la pratique, vous ayez à gérer du code asynchrone. L'une des opérations asynchrones les plus courantes consiste à envoyer une demande à une API. Pour les besoins de cet exemple, l'API JSONPlaceholder est utilisée , qui contient des données conditionnelles et répertorie les publications. Voici ce que nous allons faire ici:

  • Nous enregistrons le tableau pour le publier dans l'Ă©tat de l'application.
  • Nous appelons, en utilisant la mĂ©thode appropriĂ©e, fetch() , indiquant l'URL dont nous avons besoin, attendons que les donnĂ©es arrivent, analysons le code JSON reçu, qui est un tableau d'objets, et enfin mettons Ă  jour la variable posts en y Ă©crivant les donnĂ©es reçues.
  • Nous affichons un bouton sur la page qui appelle la mĂ©thode qui charge la liste des publications.
  • RĂ©pertoriez les publications des posts aide des touches.

Considérons un code qui implémente le schéma d'action ci-dessus.

▍ Réagir


 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")); 

â–ŤVue


 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" }); 

â–ŤHyperapp


 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


Analysons ce code et comparons les trois cadres étudiés.

  • Comme dans l'exemple prĂ©cĂ©dent, le stockage de l'Ă©tat de l'application, la sortie des donnĂ©es et la connexion Ă  l'Ă©lĂ©ment de page sont très similaires dans les trois cadres. Ici, les mĂŞmes diffĂ©rences sont observĂ©es, que nous avons dĂ©jĂ  mentionnĂ©es ci-dessus.
  • Le tĂ©lĂ©chargement de donnĂ©es Ă  l'aide de la fonction fetch() est une opĂ©ration assez simple; elle fonctionne comme prĂ©vu dans tous les frameworks. La principale diffĂ©rence ici, cependant, est que Hyperapp prend en charge les opĂ©rations asynchrones un peu diffĂ©remment des autres frameworks. Au lieu de modifier l'Ă©tat directement, dans une action asynchrone, cette action appelle une autre action synchrone, qui reçoit les donnĂ©es et les convertit dans un format appropriĂ©. Cela rend le cĹ“ur de l'application plus fonctionnel et mieux adaptĂ© Ă  la fragmentation en petites pièces susceptibles d'ĂŞtre rĂ©utilisĂ©es. Cette approche permet en outre d'Ă©viter certains des problèmes inhĂ©rents aux rappels imbriquĂ©s qui peuvent survenir dans des situations comme celles-ci.
  • Si nous parlons de la taille du code, l'application Hyperapp a encore besoin de moins de lignes de code pour atteindre le mĂŞme objectif, mais le code Vue semble plus court, et si vous comptez le nombre de caractères dans le code, il est plus court que les autres options.

â–Ť Conclusions


L'exécution d'opérations asynchrones s'est avérée tout aussi simple dans tous les cadres. Hyperapp peut conduire le développeur à écrire du code plus fonctionnel et modulaire lorsqu'il travaille avec des actions asynchrones, mais les deux autres frameworks font également un excellent travail de leur tâche et, à cet égard, donnent au développeur la possibilité de choisir.

Exemple 3: répertorier le composant d'élément pour une application To-Do


Les applications To-Do sont probablement l'exemple le plus connu en programmation réactive. Apparemment, quelque chose de similaire a été implémenté en utilisant presque tous les frameworks existants. Ici, nous n'implémenterons pas l'intégralité de l'application. Au lieu de cela, concentrons-nous sur un composant sans état simple afin d'explorer les possibilités des frameworks à l'étude pour créer de petits blocs de construction d'applications Web pouvant être réutilisés.

Considérons l'implémentation du composant en utilisant les frameworks étudiés. Dans cet exemple, nous développerons cependant les options de code à l'étude en considérant un composant React écrit dans un style fonctionnel.

▍ Réagir (style fonctionnel)


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

▍ Réagir


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

â–ŤVue


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

â–ŤHyperapp


Veuillez noter que Hyperapp utilise également un style fonctionnel.

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

â–ŤAnalyse


  • React, en ce qui concerne l'utilisation de modèles de codage, est le cadre le plus flexible. Il prend en charge les composants fonctionnels, ainsi que les composants conçus comme des classes. De plus, React, dans sa forme standard, prend Ă©galement en charge les composants Hyperapp.
  • Hyperapp prend Ă©galement en charge les composants fonctionnels de React. Cela signifie que lorsque vous travaillez avec Hyperapp et React, il y a beaucoup de place pour l'expĂ©rimentation.
  • Vue se classe dernier dans ce test. Il a une syntaxe assez Ă©trange qui est difficile Ă  comprendre tout de suite, mĂŞme pour ceux qui connaissent React ou Hyperapp.
  • Si nous parlons de la longueur du code, tous les exemples ont des tailles très similaires. La seule chose que l'on peut noter ici est que le code sur React, dans l'une des options, s'est avĂ©rĂ© ĂŞtre un peu plus volumineux que dans l'autre.

â–Ť Conclusions


Il faut un certain temps pour s'habituer à Vue, car ses modèles sont légèrement différents des modèles des deux autres frameworks. React est extrêmement flexible, il prend en charge diverses approches utilisées pour créer des composants. Dans le même temps, tout est très simple dans Hyperapp, et il est également compatible avec React, ce qui vous permet de changer le framework, si nécessaire, à un certain stade du projet.

Comparaison des méthodes de cycle de vie des composants


Une autre considération importante affectant le choix d'une infrastructure est les événements de cycle de vie des composants qu'elle prend en charge, auxquels vous pouvez vous abonner et que vous pouvez traiter en fonction des besoins du développeur. Voici un tableau basé sur une analyse de l'API des systèmes à l'étude.
Événement
Réagir
Vue
Hyperapp
Initialisation
constructeur
beforeCreate, créé
-
Montage
comoinentDidMount
avantMonté, monté
créer
Mettre Ă  jour
componentDidUpdate
beforeUpdate, mis Ă  jour
mise Ă  jour
Démontage
componentWillUnmount
-onremove
Destruction
-avant Détruire, détruit
ondestroy

â–ŤAnalyse


Voici ce que vous pouvez comprendre en analysant ce tableau:

  • La plupart des crochets de cycle de vie se trouvent dans Vue. Avec leur aide, le programmeur a la possibilitĂ© de traiter tout ce qui se passe avec le composant, soit avant que l'Ă©vĂ©nement correspondant soit appelĂ©, soit après. Cela peut ĂŞtre utile pour gĂ©rer des composants complexes.
  • Les crochets du cycle de vie de React et Hyperapp sont très similaires, bien que React combine le traitement des Ă©vĂ©nements qui se produisent lors du dĂ©montage et de la destruction d'un composant, tandis que Hyperapp agit Ă©galement avec les Ă©vĂ©nements de crĂ©ation et de montage d'un composant. Les deux offrent au dĂ©veloppeur un nombre suffisant de possibilitĂ©s de traitement des Ă©vĂ©nements du cycle de vie.
  • Vue ne gère pas l'Ă©vĂ©nement de dĂ©montage (pour autant que vous puissiez le comprendre en analysant l'API du framework), mais s'appuie plutĂ´t sur des hooks associĂ©s Ă  la destruction du composant. React ne gère pas un Ă©vĂ©nement de suppression de composant, ce qui permet de traiter uniquement un Ă©vĂ©nement de dĂ©montage de composant. Hyperapp ne propose pas de hooks pour gĂ©rer les Ă©vĂ©nements de crĂ©ation de composants, mais s'appuie entièrement sur les Ă©vĂ©nements de montage. Selon vos besoins et votre expĂ©rience, ces diffĂ©rences doivent ĂŞtre prises en compte lors de la conception d'une application, en tenant compte de la possibilitĂ© de traiter les Ă©vĂ©nements du cycle de vie des composants.

â–Ť Conclusions


En général, on peut noter que les méthodes de gestion des événements qui se produisent pendant le cycle de vie des composants prennent en charge tous les cadres. Ces méthodes résoudront de nombreux problèmes. Les trois cadres offrent des crochets pour toutes sortes d'événements, mais il existe des différences mineures entre eux, dont la source peut être les caractéristiques internes des cadres et les différences dans leur mise en œuvre. Vue dans ce domaine a peut-être une longueur d'avance sur les autres systèmes, offrant un système de traitement des événements plus détaillé, vous permettant de gérer les événements du cycle de vie avant ou après qu'ils se produisent.

Comparaison des performances du framework


En plus de la commodité de l'utilisation du cadre et des techniques de programmation utilisées pour travailler avec lui, de nombreux développeurs sont sérieusement préoccupés par les performances des cadres, en particulier pour les applications assez complexes. Le projet js-framework-benchmark est une source précieuse d'informations sur les performances de divers frameworks.

Par conséquent, jetez un œil aux résultats des tests de React, Vue et Hyperapp.

â–ŤTravailler avec des tables


Voici les résultats des tests des frameworks pour travailler avec des tables. L'indicateur dans les cellules du tableau correspond à la durée de l'opération ± écart type. Le résultat de la division de l'indicateur obtenu par le meilleur indicateur est indiqué entre parenthèses.


Analyse


  • Les opĂ©rations dans lesquelles les clĂ©s (sans clĂ©) ne sont pas utilisĂ©es pour la sortie de donnĂ©es sont beaucoup plus rapides que les opĂ©rations dans lesquelles les clĂ©s sont utilisĂ©es (avec clĂ©).
  • La plus rapide des six options considĂ©rĂ©es est celle qui utilise React sans utiliser de touches, ce qui montre des performances impressionnantes dans tous les tests.
  • Si vous comparez Vue et React lorsque vous travaillez avec des clĂ©s, Vue prĂ©sente un lĂ©ger avantage. Dans le mĂŞme temps, si vous comparez React et Vue dans des variantes oĂą les clĂ©s ne sont pas utilisĂ©es, Vue affiche des performances nettement infĂ©rieures Ă  React.
  • Vue et Hyperapp, comme vous pouvez le voir sur les rĂ©sultats, ont quelques difficultĂ©s avec le test, dans lequel la mise Ă  jour partielle du tableau est effectuĂ©e, et React s'y montre bien, probablement en raison d'une optimisation visant Ă  accĂ©lĂ©rer de telles opĂ©rations.

â–ŤChargement, lancement, tailles de code


Voici un tableau avec les résultats d'une étude d'indicateurs liés à la vitesse de lancement du framework, à sa taille, à son utilisation du thread principal.


Analyse


  • Le code Hyperapp s'est avĂ©rĂ© ĂŞtre le plus petit parmi les frameworks Ă©tudiĂ©s. Les codes React et Vue ont Ă  peu près la mĂŞme taille.
  • Hyperapp a besoin de moins de temps pour se lancer. La raison de cela, bien sĂ»r, est la petite taille du code cadre et l'approche minimaliste de la conception de son API.
  • Vue, en ce qui concerne le temps nĂ©cessaire pour lancer le framework, est un peu plus rapide que React.

▍Travailler avec la mémoire


Considérez maintenant les résultats du test d'allocation de mémoire.


Analyse


  • Hyperapp est le framework le moins exigeant en termes de consommation de mĂ©moire.
  • En gĂ©nĂ©ral, on peut noter que tous les frameworks ne consomment pas beaucoup de mĂ©moire. Cela suggère qu'ils fonctionneront Ă  peu près de la mĂŞme manière sur les ordinateurs modernes.

â–Ť Conclusions


Si, lors du développement d'un projet, vous avez besoin d'atteindre des performances maximales, vous devez comprendre, d'une part, quel type d'application vous développez, et d'autre part, de déterminer clairement les besoins de cette application. Si vous combinez l'analyse des performances des trois cadres, vous avez le sentiment que Vue et React sont mieux adaptés aux applications plus complexes, et Hyperapp est meilleur aux applications à plus petite échelle qui ont besoin de traiter moins de données, ce qui nécessite un lancement aussi rapide que possible, et qui peut avoir besoin de travailler sur les ordinateurs les moins rapides.

Cependant, il convient de rappeler que les tests de performances utilisés ici sont loin de la réalité, d'une sorte de scénario moyen. Par conséquent, après les avoir testés et comparés sur un projet réel, vous pouvez voir d'autres résultats.

Notes supplémentaires


Il convient de noter que la comparaison de cadres Web peut ressembler à quelque chose comme la comparaison de pommes et d'oranges. Voici quelques autres considérations concernant React, Vue et Hyperapp qui peuvent être utiles pour choisir un cadre spécifique pour un projet:

  • React contourne le problème selon lequel les Ă©lĂ©ments JSX voisins doivent ĂŞtre enveloppĂ©s dans l'Ă©lĂ©ment parent, introduisant le concept de fragments - des Ă©lĂ©ments qui vous permettent de regrouper un ensemble d'Ă©lĂ©ments descendants sans ajouter de nĹ“uds supplĂ©mentaires au DOM.
  • React fournit au dĂ©veloppeur des composants d'ordre supĂ©rieur , tandis que Vue utilise des mixins pour rĂ©utiliser les fonctionnalitĂ©s des composants.
  • Vue utilise plus pleinement le concept de sĂ©paration des responsabilitĂ©s, en sĂ©parant la structure et les fonctionnalitĂ©s de l'application Ă  l'aide de modèles .
  • Hyperapp, comparĂ© Ă  React et Vue, ressemble Ă  un système qui fournit une API de niveau infĂ©rieur. Le code des applications Hyperapp s'avère plus court, il offre une grande flexibilitĂ©, ce qui peut ĂŞtre utile dans les cas oĂą le dĂ©veloppeur peut vouloir s'y attaquer en affinant et en recherchant ses mĂ©canismes internes.

Résumé


L'auteur de ce document estime que si vous lisez jusqu'à présent, vous savez déjà lequel des cadres étudiés ici correspond le mieux à vos besoins. En fin de compte, nous ne parlions pas duquel des cadres est le meilleur, mais plutôt de celui qui est le mieux à même de se manifester dans diverses situations. En conséquence, nous pouvons tirer les conclusions générales suivantes:

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

! -?


, - 10% :)

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


All Articles