loading...

Svelte VS ReactJS Performance Report

Vani Shivanand on January 11, 2020

A few days before a post was made on Svelt Needs A Virtual DOM. Maybe there was a kind of lack of clarity in the same post from my side. To clarify... [Read Full]
markdown guide
 

Hello Vani, interesting post but, can you share both codes so we can run and test by ourselves?

I've created the tests based on your post, and I didn't had the same results:
github.com/marceloadsj/dev-to-reac...

If you stop to think on the tasks at runtime the frameworks needs to run, the result make sense:

1) Download the bundle of the framework itself (svelte have a light runtime layer, and react have the main lib + react-dom layer)

2) Parse the script and run the first render (both, I'm not considering any SSR)

3) Receive the calls to set the new state (both, react uses this.setState on classes, and svelte use $$invalidate on assignments)

*important point on bullet 3

  • React, after receive a call on setState, on the next tick will run the reconciliation process to get the list of changes and then, update the dom.

  • Svelte receive a call on $$invalidate, and on the next tick will update the dom.

  • On Both: If the same state is updated synchronously, don't matter, both fw will get the last one to change the dom, once, on the next tick.

4) Compare the virtual dom to create the list of things that need to be updated (react only, svelte do this list of updates at compile time)

5) Update the dom with the new values (both, of course, haha)


So, svelte have lighter bundle (a small runtime layer with helper fns only), and the list of updates is created on build time. Even, if your app don't use some function, let's say, your app never update any element attribute, then svelte will not inject that function in your runtime layer, no dead code on clients.

React, instead, have a bigger bundle to ship the reconciliation code, + the react-dom that handle all the api to update the dom. The list of updates are created runtime doing a comparison between the last state and the new one, using a virtual dom.

Both apps, at the end, will update the dom. But just one will need to do some extra work to know how to update the dom properly. The other already have all the instructions directly on the compiled code.


Builded versions running side by side:

Network (local server):

  • Svelte:
    svelte network

  • React:
    react network

The main bundle size difference is really noticeable, more than 10 times.

Performance (Chrome on a Macbook Pro 2014):

  • Svelte:
    svelte performance

  • React:
    react performance

Scripting have a big difference, almost 3 times.


Of course, If I'm wrong on any detail of that post, let me know. At all, we are all here to grow and learn. Haha. :D


Some usefull links:

Interesting link about svelte scalability (theorically only):
github.com/sveltejs/svelte/issues/...

One of the bullets on react docs, on topic of performance, says "avoid reconciliation", so it already answer a lot of questions haha:
reactjs.org/docs/optimizing-perfor...

The homepage of preact (alternative fw to react with same api) says interesting points about things we are discussing here, like bundle, performance:
preactjs.com/

 

Interesting! I had a look at your github. I exactly had the same code. I also got the same scripting time but my rendering time had a huge difference. I shall consider re-running the test code.

Scripting time will be more because it was considered by any virtual-dom framework that to re-draw the tree should be optimized more than the amount of javascript that is being run.

The reason, I feel it is okay to compromise with the scripting time as scripting time is always a lot lesser than render time.

Also, I personally want to try on a high-data loaded app with svelte. Because react/vue has proved their ability over larger sites.

Thank you for the comment.

 

I've added the two bundles on a gist, so we can check and compare (I've tried to not minify it):

React - 10572 loc:
gist.github.com/marceloadsj/79a18b...

react.production.min.js (minified): gist.github.com/marceloadsj/79a18b...

react-dom.production.min.js (minified): gist.github.com/marceloadsj/79a18b...

--

Svelte - 450 loc:
gist.github.com/marceloadsj/79a18b...

That's a huge difference, haha.

--

I think a better approach to test would be checking the Real World Example repo: github.com/gothinkster/realworld

Did you already checked both (react & svelte)?

I suggest you to try, run locally, check the devtools and everything. It can give you more insights of a real usage instead of just random loops and updates.

Other good resource is: github.com/krausest/js-framework-b...
it's not realistic but can show more informations about a lot of distinct scenarios.

--

I agree with you, React, Vue and Angular are battle tested frameworks, but I think It's just because they are older than Svelte. I hope more devs can try and help improve more and more that amazing compiler/framework.

list of companies using svelte
from svelte.dev

The huge difference is obvious. If we do the same with any lighter framework it will be lesser than react/vue. That's not the point.

Yes, I shall try on a real time app but it takes a lot of time. I will pull out some and work on the same.

I don't know if you didn't got that, but, It's not lighter because the framework itself is smaller, but because Svelte don't inject unused code on the bundle! haha

And, of course, because svelte don't need to have a layer to match an in memory DOM, to extract which kind of update needs to be done. This mean less work, faster execution.

It's easy:
Both apps, at the end, will need to update the DOM, but just one will need to run an expensive comparison heuristic to know how to update it properly. The other already knows how to do it at compile time. :)

I get it. It's obvious. Svelte doesn't have boilerplate code and it compiles the code to javascript. Hence less work at run time.

Before any virtual-dom frameworks came up, we were always working without having a layer to match DOM. Svelte does a lot of optimization while it compiles the code but my concern is, it doesn't handle all the cases. But this I am not very sure about.

It's not that easy. If all that we need to do is a DOM update, even jquery did that and without a framework also people did that.

Nothing offensive, it's just that a lot of things to be analyzed before arriving at the conclusion.

Why you don't think it handle all the cases?

At runtime, react analysis the changes and create a list of updates.
At compile time, svelte analysis the changes and inject the list of updates.

The only difference, for me, it's the time it get the list of updates, isn't it?
I think I'm not getting the point you're trying to say with the posts.

And, you're right, the fastest way you can code is in vanilla js, but you'll have to code all the possible changes on the dom, in a performant way (without causing reflows). We current have only two solutions to not do all those things by hand: virtual dom runtime analysis and compile time analysis.

Well, consider a scenario where a Facebook live video of a president or a celebrity is happening.

A lot of users are commenting & reacting to the live video. And say another person who is watching live, also is getting an update on another post on the same page.

Here is where the run time comparision comes in. I am yet to know how svelte handles this.

This is one of the case. What will I answer by "all the cases"? Simple answer will be it is not that simple.

Let's think on that the problem describing as a mind exercise.

First, we can assume the browser running at 60 fps to be a smooth experience.

That means the js have 16.7ms on each tick to run + let the browser recalculate the layout and repaint.

Then, on the scenario you described, facebook have some ways to implement this, like:

  • websocket connection so the client get's all messages, one by one;
  • long polling, so the client send a request the server can hold until it get a new message, and repeat;
  • some interval implementation like, every 10 seconds, the client sends a request, the server send back a list of messages of the last 10 seconds, and the client render those one by one by the next 10 seconds;
  • some mix of those approaches;
  • other ways I can't remember or I don't know, haha;

The thing is, if at some exact time, the client receives a bunch of messages/comments, let's say, 100 new items, what can happen:

  • our react component will have an array of msgs, and a loop to render all. We received +100, so, we will render +100 new items on the list. It will basically run the reconcilliation algorithm and, 100 element.appendChild being called on the next tick;

  • on svelte, it will be exactly the same, 100 appendChild being called. The difference will be svelte already knowing that it needs to run appendChild (in that case, I think it will be insertBefore with an anchor, but we can consider the same);

Svelte implementation to see the insertBefore being called 100 times:
svelte.dev/repl/9e9e86a21f8c4c0ab6...

  • Just one detail, Svelte injects one empty text node at the end of the list to use as an anchor!

React implementation to see the appendChild being called 100 times:
jsfiddle.net/98puyLoz/

PS: on both, open the devtools and click on show, haha!


So, yep, the biggest impact will be on diff algorithm and the most important part to consider will be on the behavior you choose to code (receive and render one by one, receive a batch and render all, receive real time or each N seconds).

I am sorry to say but your "haha" is quite irritating. I wonder if it comes under "Code of conduct".

Anyway, before even I think of opening devtools, I would say the DOM structure in your example is nowhere near to real-time updates. Unless the DOM has complex structure Svelte will always be faster. The code that is written in the provided link is synchronous update whereas in realtime we receive lakhs of asynchronous updates for a celebrity live video. Please let's understand the basics of real-time updates.

I would prefer to work on it for a couple of days offline and then discuss again. I wouldn't be able to answer again on this thread. I would be grateful if you also help in closing this for now. Thanks for understanding.

[deleted]

They are nowhere realtime examples and that was judging & rude.

 

What about doing this for vuejs as well.

 

I shall give a try in some time. Thanks for the suggestion.

 

Proper benchmarks have to come with the exact code (repo) that was used so they could be independently reproduced.
Based on what I know about the internals of Svelte (well, svelte actually shows the code it produces in the Repl so it is quite easy to verify) and React, these results don't seem plausible.
I am sure you have no intention of spreading misinformation but I'm afraid both this article and the one on Svelte needing a virtual DOM are doing exactly that.
With that said, I enjoyed reading the discussions that the article provoked.

 

I heard about a new js framework based on react called preact and they claim that it's better performance is it true ?

 

Everytime I see a new benchmark I find it useful to categorize to understand what it is showing. This seems to be of the data snapshot type.

medium.com/javascript-in-plain-eng...

 

I will have a look. Thank you!

code of conduct - report abuse