This is a short reply to the article
“Comparison of JS frameworks: React, Vue and Hyperapp” . Actually, I'm not a big fan of such comparisons. However, since we are talking about such a marginal framework as Hyperapp, in comparison with mastodons like React and Vue, I thought, why not consider all the same examples on
Svelte . So to speak, to complete the picture. Moreover, it will take literally 5 minutes. Go!

If suddenly you are not familiar with
Svelte and the concept of endangered frameworks, you can read the articles
“Magically Disappearing JS Framework” and
“Disappearing Framework” .
For the convenience of readers, I copied the examples from the
original article under the spoilers to make it easier to compare. Well, let's get started.
')
Example number 1: application counter
Reactimport 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>
→
working example.▍Analysis
The
Svelte component is an html file that has the well-known Single File Component (SFC) format, in one form or another, already used in
Vue ,
Ractive ,
Riot, and some other frameworks. In addition to the html-template itself, a component can have behavior and logic described in javascript, as well as scoped-styles of the component.
No part of the component is required, so the counter component can consist only of the html template of the counter itself. To change the value of the
count variable, the click handler uses the built-in method of the
set () component described in the
documentation .
Example 2: working with asynchronous code
React 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>
→
working example.▍Analysis
Unlike JSX, which, like a carbon copy, is used in all 3 frameworks from the original comparison, and in fact extends the javascript code with html-like syntax,
Svelte uses more familiar features - the introduction of js and css code in html using tags
< script> and
<style> .
The component script exports a simple JS object divided into sections. The
methods section describes component methods that can be used through the component instance and in event handlers. So, when you click a button, the
getData () method is
called , inside which data is requested and upon completion of the operation, the data is simply set to the component state and immediately drawn in the template.
Note the use of the destructuring of the publication object (post) at each step of the iteration of the list of publications:
{#each posts as {title, body}}
This trick allows you to avoid redundancy in templates like
{post.title} and visually simplify the templates using a shorter
{title} .
Example 3: list item component for a To-Do application
React (functional style) function TodoItem(props) { return ( <li class={props.done ? "done" : ""} onclick={() => props.toggle(props.id)}> {props.value} </li> ); }
React 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>
→
working example.▍Analysis
It's all pretty trite. We set the css class depending on the
done value and change this value to the opposite when clicking on the list item.
Comparing Component Life Cycle Methods
Disclaimer : From this point on, I decided to omit the comparison with Hyperapp, because otherwise the tables will simply be unreadable.Event
| React
| Vue
| Svelte
|
Initialization
| constructor
| beforeCreate, created
| onstate |
Mounting
| componentDidMount
| beforeMount, mounted
| oncreate, onupdate
|
Update
| componentDidUpdate
| beforeUpdate, updated
| onstate, onupdate
|
Unmounting
| componentWillUnmount
| - | ondestroy |
Destruction
| - | beforeDestroy, destroyed
| - |
▍Analysis
Svelte is extremely minimalistic, including in terms of life cycle hooks. There are only 4 hooks:
- onstate is called before the component is created and each state change before the DOM update.
- oncreate - the time when the component is created is called.
- onupdate - called immediately after mounting to the DOM and every change of the state after updating the DOM.
- ondestroy - called when a component is destroyed and removed from the DOM.
Framework Performance Comparison
Honestly, I do not know what to comment here. Benchmarks themselves and the way they are executed always causes a lot of controversy, so I don’t think that it makes sense to focus too much.
However, we still have no other data.
▍Work with tables

▍Download, launch, code sizes

▍Working with memory

▍Analysis
Judging by the numbers,
Svelte is quite fast, it “eats” little memory (also because it does not use VirtualDOM), it starts up quickly and is small in size.
In general, to say that the results of the benchmarks of these 3 frameworks differed dramatically, I can not. However, only
Svelte has an exclusively “green” bar, i.e. it is good enough at once for all indicators, and therefore it is perfectly balanced and has no obvious distortions either in speed or in memory consumption and other metrics. In general, with it you can safely start any project, from the usual web, to mobile devices, Smart TV and more exotic systems.

Results
Svelte is a great tool for creating components of almost any web application. It is as powerful as React and although it still has a much smaller community, it requires less effort to master. It is as flexible as Vue, while much more minimalist and verified, since it does not try to grab onto all the ideas of modern web development right away.
In addition, he is the only one using the concept of
endangered frameworks . In other words, it has no specific
runtime , except the browser itself.
Applications on it turn out fast, not exacting to resources and small in size. In addition,
Svelte can be "seamlessly" used in applications written in other frameworks, which I plan to write about next time.
If you first met this wonderful framework, you may be interested to read other articles about it:
→
Magically vanishing JS framework→
1Kb autocomplete→
SvelteJS: Second Version ReleaseIf you have any questions about
Svelte , join the Russian
telegram channel SvelteJS . There you can always ask a question and get advice, find out the latest news, and just have a nice chat. We will be glad to you!