Este es un pequeño artículo de respuesta a la publicación
"Comparación de marcos JS: React, Vue e Hyperapp" . En general, no soy un gran admirador de tales comparaciones. Sin embargo, dado que estábamos hablando de un marco tan marginal como Hyperapp, en comparación con mastodontes como React y Vue, pensé, ¿por qué no considerar los mismos ejemplos en
Svelte ? Por así decirlo, para completar la imagen. Además, lleva literalmente 5 minutos. Vamos!

Si de repente no está familiarizado con
Svelte y el concepto de marcos desaparecidos, puede leer los artículos
"Marco JS que desaparece mágicamente" y
"Marco que desaparece" .
Para comodidad de los lectores, copié los ejemplos del
artículo original debajo de los spoilers para que sea más conveniente comparar. Bueno, empecemos.
Ejemplo No. 1: aplicación de contador
Reaccionarimport 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>
→ Un
ejemplo de trabajo.▍Análisis
Un componente
Svelte es un archivo html que tiene el notorio formato de componente de archivo único (SFC), de una forma u otra, ya utilizado en
Vue ,
Ractive ,
Riot y algunos otros marcos. Además de la plantilla html en sí, un componente puede tener el comportamiento y la lógica descritos en javascript, así como los estilos de alcance del componente.
No se requiere ninguna parte del componente, por lo tanto, el componente del contador puede consistir solo en la plantilla html del contador en sí. Para cambiar el valor de la variable de
recuento , el controlador de clics utiliza el método incorporado del componente
set () descrito en la
documentación .
Ejemplo No. 2: trabajar con código asincrónico
Reaccionar 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>
→ Un
ejemplo de trabajo.▍Análisis
A diferencia de JSX, que, como una copia al carbón, se usa en los 3 marcos de la comparación original, y de hecho extiende el código de JavaScript con una sintaxis tipo html,
Svelte usa características más familiares: incrustando código js y css en html usando
< script> y
<style> .
El script de componente exporta un objeto JS simple, dividido en secciones. La sección de
métodos describe los métodos de componentes que se pueden utilizar a través de la instancia del componente y en los controladores de eventos. Entonces, cuando hace clic en el botón, se
llama al método
getData () , dentro del cual se solicitan los datos y al finalizar la operación, los datos simplemente se instalan en el estado del componente y se dibujan inmediatamente en la plantilla.
Tenga en cuenta el uso de la desestructuración del objeto de publicación (publicación) en cada paso de la iteración de la lista de publicación:
{#each posts as {title, body}}
Este truco evita la redundancia en plantillas como
{post.title} y simplifica visualmente las plantillas con una entrada más corta
{título} .
Ejemplo 3: enumerar el elemento del elemento para una aplicación de tareas pendientes
Reaccionar (estilo funcional) function TodoItem(props) { return ( <li class={props.done ? "done" : ""} onclick={() => props.toggle(props.id)}> {props.value} </li> ); }
Reaccionar 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>
→ Un
ejemplo de trabajo.▍Análisis
Aquí todo es bastante banal. Exponemos la clase css dependiendo del valor
hecho y cambiamos este valor a lo opuesto cuando haces clic en un elemento de la lista.
Comparación de los métodos del ciclo de vida de los componentes.
Descargo de responsabilidad : a partir de ahora, decidí omitir la comparación con Hyperapp, porque de lo contrario las tablas serían simplemente ilegibles.▍Análisis
Svelte es extremadamente minimalista, incluso en términos de ganchos de ciclo de vida. Solo hay 4 ganchos:
- onstate: se llama antes de que se cree el componente y cada cambio de estado antes de que se actualice el DOM.
- oncreate: el momento en que se crea el componente se llama.
- onupdate: se llama inmediatamente después del montaje en el DOM y cada cambio de estado después de actualizar el DOM.
- ondestroy: se llama cuando el componente se destruye y se elimina del DOM.
Comparación de rendimiento del marco
Honestamente, no sé sobre qué comentar. Los puntos de referencia en sí mismos y la forma en que se ejecutan siempre generan mucha controversia, por lo que no creo que tenga sentido centrar innecesariamente la atención.
Sin embargo, todavía no tenemos otros datos.
▍Trabajar con mesas

▍ Carga, lanzamiento, tamaños de código

▍Trabajando con memoria

▍Análisis
A juzgar por los números,
Svelte es bastante rápido, "come" poca memoria (incluso porque no usa VirtualDOM), se inicia rápidamente y tiene un tamaño pequeño.
En general, no puedo decir que los resultados de los puntos de referencia de estos 3 marcos diferían drásticamente. Sin embargo, solo
Svelte tiene una columna exclusivamente "verde", es decir es bastante bueno a la vez en todos los aspectos, lo que significa que está perfectamente equilibrado y no tiene distorsiones obvias ni en la velocidad ni en el consumo de memoria ni en otras métricas. En general, con él puede iniciar de forma segura cualquier proyecto, desde la web habitual, hasta dispositivos móviles, Smart TV y sistemas más exóticos.

Resumen
Svelte es una gran herramienta para construir componentes de casi cualquier aplicación web. Es tan poderoso como React, y aunque tiene una comunidad significativamente más pequeña, requiere menos esfuerzo para dominarlo. Es flexible, como Vue, mientras que es mucho más minimalista y verificado, ya que no trata de captar de inmediato todas las ideas del desarrollo web moderno.
Además, él es el único que utiliza el concepto de
marcos en peligro de
extinción . En otras palabras, no tiene un
tiempo de ejecución específico que no sea el navegador en sí.
Las aplicaciones en él resultan rápidas, no requieren recursos y son de tamaño pequeño. Además,
Svelte se puede usar "sin problemas" en aplicaciones escritas en otros marcos, sobre los cuales planeo escribir la próxima vez.
Si conoció por primera vez este maravilloso marco, podría estar interesado en leer otros artículos al respecto:
→
Marco JS que desaparece mágicamente→
Autocompletar 1Kb→
SvelteJS: Lanzamiento de la segunda versiónSi todavía tiene preguntas sobre
Svelte , únase al
canal de telegramas en ruso
SvelteJS . Allí siempre puede hacer una pregunta y obtener consejos, conocer las últimas noticias y simplemente disfrutar chateando. Estaremos encantados de verte!