Re: “Comparação de frameworks JS: React, Vue e Hyperapp”

Este é um pequeno artigo de resposta à publicação "Comparação de estruturas JS: React, Vue e Hyperapp" . Em geral, eu não sou um grande fã dessas comparações. No entanto, como estávamos falando de uma estrutura marginal como a Hyperapp, em comparação com mastodontes como React e Vue, pensei, por que não considerar os mesmos exemplos no Svelte . Por assim dizer, para completar a imagem. Além disso, leva literalmente 5 minutos. Vamos lá!

imagem

Se de repente você não estiver familiarizado com o Svelte e o conceito de estruturas em desaparecimento, poderá ler os artigos “Magically Disappearing JS Framework” e “Disappearing Framework” .

Para conveniência dos leitores, copiei os exemplos do artigo original sob os spoilers para facilitar a comparação. Bem, vamos começar.

Exemplo nº 1: contra-aplicação


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


▍Svelte


 <div> <h1>{count}</h1> <button on:click="set({count: count - 1})">-</button> <button on:click="set({count: count + 1})">+</button> </div> 

→ Um exemplo de trabalho.

▍Análise


Um componente Svelte é um arquivo html que possui o notório formato SFC (Single File Component), de uma forma ou de outra, já usado no Vue , Ractive , Riot e em outras estruturas. Além do próprio modelo html, um componente pode ter o comportamento e a lógica descritos em javascript, além de estilos de escopo do componente.

Nenhuma parte do componente é necessária; portanto, o componente do contador pode consistir apenas no modelo html do próprio contador. Para alterar o valor da variável count , o manipulador de cliques usa o método interno do componente set () descrito na documentação .

Exemplo No. 2: Trabalhando com Código Assíncrono


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


▍Svelte


 <div> <button on:click="getData()">Get posts</button> {#each posts as {title, body}} <div> <h2><font color="#3AC1EF">{title}</font></h2> <p>{body}</p> </div> {/each} </div> <script> export default { methods: { getData() { fetch('https://jsonplaceholder.typicode.com/posts') .then(res => res.json()) .then(posts => this.set({ posts })); } } }; </script> 

→ Um exemplo de trabalho.

▍Análise


Diferentemente do JSX, que, como uma cópia carbono, é usado em todas as três estruturas da comparação original e, na verdade, estende o código javascript com sintaxe semelhante a html, o Svelte usa recursos mais familiares - incorporando códigos js e css em html usando < script> e <style> .

O script do componente exporta um objeto JS simples, dividido em seções. A seção métodos descreve métodos de componentes que podem ser usados ​​por meio da instância do componente e nos manipuladores de eventos. Portanto, quando você clica no botão, o método getData () é chamado , dentro do qual os dados são solicitados e, após a conclusão da operação, os dados são simplesmente instalados no estado do componente e imediatamente desenhados no modelo.

Observe o uso da destruição do objeto de publicação (postagem) em cada etapa da iteração da lista de publicações:

 {#each posts as {title, body}} 

Esse truque evita redundância em modelos como {post.title} e simplifica visualmente os modelos usando uma entrada mais curta {title} .

Exemplo 3: componente de item de lista para um aplicativo de Tarefas Pendentes


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


Reagir
 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
 const TodoItem = ({ id, value, done, toggle }) = ( <li class={done ? "done" : ""} onclick={() => toggle(id)}> {value} </li> ); 


▍Svelte


 <li class="{done ? 'done' : ''}" on:click="set({done: !done})">{value}</li> 

→ Um exemplo de trabalho.

▍Análise


Tudo é bastante banal aqui. Nós expomos a classe css dependendo do valor concluído e alteramos esse valor para o oposto quando você clica em um item da lista.

Comparação dos métodos do ciclo de vida dos componentes


Isenção de responsabilidade : A partir de agora, decidi omitir a comparação com o Hyperapp, porque, caso contrário, as tabelas seriam simplesmente ilegíveis.

Evento
Reagir
Vue
Svelte
Inicialização
construtor
beforeCreate,
criado
no estado
Montagem
componentDidMount
beforeMount, montado
oncreate, onupdate
Update
componentDidUpdate
beforeUpdate, atualizado
onstate, onupdate
Desmontando
componentWillUnmount
-ondestroy
Destruição
-antes de destruir, destruído
-

▍Análise


O Svelte é extremamente minimalista, inclusive em termos de ganchos do ciclo de vida. Existem apenas 4 ganchos:

  • onstate - chamado antes da criação do componente e cada estado muda antes da atualização do DOM.
  • oncreate - o momento em que o componente é criado é chamado.
  • onupdate - chamado imediatamente após a montagem no DOM e cada estado muda após a atualização do DOM.
  • ondestroy - chamado quando o componente é destruído e removido do DOM.


Comparação de desempenho da estrutura


Sinceramente, não sei no que comentar. Os próprios benchmarks e a maneira como são executados sempre causam muita controvérsia, então não acho que faça sentido concentrar desnecessariamente a atenção.
No entanto, ainda não temos outros dados.

▍Trabalhando com tabelas




OadCarregando, iniciando, tamanhos de código




▍Trabalhando com memória




▍Análise


A julgar pelos números, o Svelte é bastante rápido, "consome" pouca memória (inclusive porque não usa o VirtualDOM), é iniciado rapidamente e tem um tamanho pequeno.

Em geral, não posso dizer que os resultados dos benchmarks dessas três estruturas diferiram drasticamente. No entanto, apenas o Svelte possui uma coluna exclusivamente "verde", ou seja, é bastante bom ao mesmo tempo em todos os aspectos, o que significa que está perfeitamente equilibrado e não possui distorções óbvias no consumo de velocidade ou memória ou em outras métricas. Em geral, com ele, você pode iniciar com segurança qualquer projeto, da Web habitual, para dispositivos móveis, Smart TV e sistemas mais exóticos.

imagem

Sumário


O Svelte é uma ótima ferramenta para criar componentes de praticamente qualquer aplicativo da web. É tão poderoso quanto o React e, embora tenha uma comunidade significativamente menor, exige menos esforço para dominar. É flexível, como o Vue, enquanto é muito mais minimalista e verificado, pois não tenta captar de uma só vez todas as idéias do desenvolvimento da web moderna.

Além disso, ele é o único que usa o conceito de estruturas ameaçadas . Em outras palavras, ele não possui tempo de execução específico além do próprio navegador.

Os aplicativos são rápidos, não exigem recursos e são pequenos em tamanho. Além disso, o Svelte pode ser "perfeitamente" usado em aplicativos escritos em outras estruturas, sobre as quais planejo escrever na próxima vez.

Se você conheceu essa estrutura maravilhosa pela primeira vez, pode estar interessado em ler outros artigos sobre ela:

Desaparecendo Magicamente o JS Framework
Preenchimento automático de 1 KB
SvelteJS: Lançamento da segunda versão

Se você ainda tiver dúvidas sobre o Svelte , entre no canal de telegrama em russo SvelteJS . Lá, você sempre pode fazer uma pergunta e obter conselhos, descobrir as últimas notícias e apenas conversar. Teremos o maior prazer em vê-lo!

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


All Articles