loading...

Discussion on: Svelte for Sites, React for Apps

ryansolid profile image
Ryan Carniato

Alpine isn't large by any means but any size conscious modern library is going to via treeshaking going to produce smaller bundles than something that isn't prebundled. Alpine isn't treeshakeable currently (2.7.0).

Memory overhead is similarly middle of the pack. It's decent but again optimized libraries are still more performant.

Performance is not a motivation to the point Alpine is one of the slowest JS libraries I have ever seen. Orders of magnitude slower even for simple update operations like updating or selecting a row. If you use it sparingly as intended you will probably not notice but scale up that usage even a little and you will.

Basically, a library like Svelte is better by every performance metric if you can get over having to run npm i.


Explanation (for lose who do want to take a minute to read):

The tests are basically a giant list management example like a TodoMVC where we are doing simple create, append, update, select, swap row, remove row, etc.. with enough rows and under CPU throttling from chrome browser to see differences between most common UI libraries. This is not the Realworld demo by any means only using the amount of features one might see in a simple admin management app. Styles are bootstrap etc...

One test measures the kilobyte weight of all assets sent over the wire. Nothing in the test is gzipped just minified. The smallest implementations come in around 143kb. Some notable results:

  • hyperapp 144.4kb
  • svelte 145.9kb
  • solid 149.5kb
  • preact 154.8kb
  • lit-html 156.5kb
  • inferno 162.9kb
  • alpine 167.9kb
  • mithril 175.2kb
  • vue 3 196.1kb
  • knockout 207.8kb
  • react 260.0kb
  • angular 295.3kb

Performance is not nearly as favourable. I respect that Alpine isn't really made to render 1000 components on a page. But how about selecting a row in a large list:

  • solid 24.8ms
  • svelte 37.1ms
  • hyperapp 45.3ms
  • inferno 49.6ms
  • preact 65.0ms
  • angular 78.3ms
  • lit-html 85.4ms
  • react 87.9ms
  • knockout 137.3ms
  • vue 3 164.7ms
  • mithril 270.5ms
  • alpine 1377.7ms

Or updating every 10th row with some additional text:

  • solid 143.9ms
  • inferno 149.3ms
  • knockout 160.0ms
  • hyperapp 160.1ms
  • preact 160.7ms
  • lit-html 168.0ms
  • angular 170.8ms
  • svelte 171.8ms
  • vue 3 183.9ms
  • react 188.6ms
  • mithril 242.1ms
  • alpine 1395.1ms

Finally looking at runtime memory with all list items on the page Alpine is middle of the pack again:

  • solid 2.2mb
  • lit-html 2.5mb
  • inferno 2.5mb
  • hyperapp 2.7mb
  • svelte 2.7mb
  • alpine 2.9mb
  • mithril 3.5mb
  • vue 3 3.5mb
  • preact 3.9mb
  • react 4.0mb
  • angular 4.2mb
  • knockout 11.6mb

*** obligatory disclaimer: this is a single benchmark scenario and not representative of all realworld apps... yada yada...

Thread Thread
khrome83 profile image
Zane Milakovic

So, I appreciate all your stats but your really missing the point.

Svelte is not smaller than Alpine. Take a standard marketing site where the header is just links. Nothing dynamic. These are still svelte components that have Javascript. But it should just be HTML.

I have a Sapper/Svelte site in production that is 126 components, but the number of those components that actually need to be dynamic on the client is less than a dozen.

And none of them have realistic performance concerns that I could not swap it out to Alpine and have the same experience for the user.

BTW Svelte and Alpine both modify the DOM and not a shadow DOM. So performance characteristics would be similar, which the exception of startup, where alpine has the parse live instead of having a JS bundle.

Tree shaking argument is mute, since Alpine is a actual library. Your not tree shaking your code. Your code is in HTML in most cases. You get too complex, use a library for a App. My argument was just simple marketing sites.

Thread Thread
ryansolid profile image
Ryan Carniato

Yeah you are right it's deeper than that. If we aren't doing the same work they arent going to be close. Which makes Elderjs interesting since it potentially could. But that also suggests JS on the server. So it isn't a swap in. But it is interesting such an approach could ship less JS. If Svelte itself is smaller and us only hydrating the necessary components.

Thread Thread
khrome83 profile image
Zane Milakovic

That would be my happy place, if we could declare what should actually be convert to a live component, vs what should be static html and is just using the life cycle to render, with a dapper framework or something similar.

Thread Thread
ryansolid profile image
Ryan Carniato

I'm fairly confident this direction is viable given Marko has been doing this at eBay since 2013. Who it is viable for is a different question. It will be interesting to see more libraries take this approach.