sveltejs / svelte

Cybernetically enhanced web apps

Home Page:https://svelte.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Yes but does it scale?

Rich-Harris opened this issue · comments

Another blog post that really needs to be on the site. Switched-on developers frequently say 'I get that the imperative update code is faster than VDOM diffing or whatever, and I understand that there's no need for a big runtime, but surely the incremental cost of a component is significantly larger? Doesn't that mean Svelte hits an inflection point where the bundle size is larger than if we'd just used a traditional framework?'

It's a good question that deserves a good answer. The bullet point version is this:

  • Theoretically, yes there is an inflection point. Where that inflection point is is the only thing that really matters. In practice, you're unlikely to hit that inflection point on any given page of your app, as long as you're using code-splitting (which Sapper gives you OOTB)
  • The incremental cost of Svelte components isn't that high. The code is designed to be readable, but also to minify really well, and it makes use of a shared internal library
  • The initial bundle size is the one that really matters. If subsequent bundles are slightly chunkier than they need to be, it's not the end of the world — because by that point we have service workers and preloading and so on
  • The beauty of the compiler-centric approach is that we can vary the target output. An example is generating string-concat code for SSR. If it ever became a real problem, we could investigate approaches like Glimmer's, where we generate bytecode instead of raw JS. We could even have different approaches within a single app — imperative JS for a fast initial load, then load the VM and use bytecode for subsequent navigations
  • Bundle size is only one facet of the Svelte experience

Of course, the best way to show this is with demo apps, such as updating the RealWorld app.

Definitely yes to all points. 👍 It will be very interesting to see the results with a (bigger) app if it really comes to an inflection point¹. I am looking forward to the results to explain plausibly to all runtime fans that there will be no or at least no noticeable increase in bundle size in a real app and if you get a bigger increase you will have some solutions. Thank you Rich for the upcoming proof!

¹Although I'd like to see when the inflection point arises (even if code-splitting is recommended) because it's something you should know when you're working with Svelte/whatever and create an EA front-end for example.

commented

Vaguely related: I've had some discussions in the past about what a good demo/ test/ benchmark app might look like. Probably out of scope for a simple blog posts but a more complex application than the real world app with the kinds of integrations that you might expect from a production app could be helpful for newcomers.

It could not only serve as an example of how to perform certain kinds of integrations (some of which the RealWorld app does) but also an example on how to achieve certain things with svelte/sapper and what an actual codebase might look like. The RealWorld app gets part of the way there but it isn't very complex at all (imo) and it doesn't really showcase many of the fetaures that Svelte brings to the table. People talk about size/ performance with Svelte a lot but the stuff that makes it really nice to use on a daily basis are often not those things but rather things like stores, transitions, actions, etc.

Integrations like custom preprocessors, testing, maybe CI etc. could also feature. They aren't as exciting as some stuff but they're a pretty standard feature of any production app and having an official test app built to our own specifications, perhaps with a 'walkthrough' of sorts might be valuable for people asking these sorts of questions.

For example many React applications use CSS-in-JS frameworks like styled-components or emotion. And their resulting css will bloat the javascript bundle size. Unlike Svelte that can split the css into static css files that can be loaded in parallel to and won’t effect the javascript bundle size.

@fiskgrodan I think you'll find that Styled Components outputs separate pure CSS files and a huge focus has been on generating as little as possible.

From Docs > Advanced > Existing CSS:

There are a couple of implementation details that you should be aware of, if you choose to use styled-components together with existing CSS.

styled-components generates an actual stylesheet with classes, and attaches those classes to the DOM nodes of styled components via the className prop. It injects the generated stylesheet at the end of the head of the document during runtime.

See also Docs > Basics > Motivation:

big runtimes are a problem when developing small simple apps used on mobile frequently by many user. The time to load and the amount of battery capacity wasted is unnecessary. In the case of a complex app sometime they work fine, sometime they bottleneck and require leg splitting to survive. But, if a big app uses a small runtime that generate a small increase in meaningful code to ensure a smooth experience and cutting edge performance, it is a positive trade. You always end up with more meaningful code when targeting performance, instead of multilayered reusable generic code. So compare loading tons of stuff for very little UI and number features (worst case big runtime) vs loading a lot to get a lot and running like it's on fire(worst case svelte), this is good stuff, don't give in to doubts about this philosophy. I also like svelte because the code it requires looks neat and simple to learn. Before I heard about svelte I was convinced vanilla was the only solution to keep the perf in check for complex mobile UI, now That I know this framework will generate the shitty but minimalist necessary code from a component and modern development style input, I can't imagine going back to writing by hand verbose vanilla ever. This is the kind of no compromise shit that the html era needs to be loved by most developers.

commented

It's worth noting that the deployed app, linked in the description, is actually the older version and doesn't currently reflect the source code in master. We've had... some issues with that deployment but we should try to sort that out.

commented

I've made a video series on the real world app if anyone wants to look WIP

https://www.youtube.com/playlist?list=PLCrwuqjmVebK08Cwz_XB55cNKFfFYOMGo

commented

I'm trying to understand if sveltestrap is an example of a larger app that has passed the infection point Rich talks about above. sveltestrap replaces jQuery and related JS components with svelte components. I analysed its JS payload and it is huge compared to the regular jQuery version. See my screenshots here and please advise... Is this a matter of further optimizing and breaking down the sveltestrap bundles?

See my screenshots here and please advise

This screenshot includes the full vendor bundle (storybook uses react). If you want to compare bootstrap + jquery to sveltestrap you should only use those dependencies not other framework dependencies that aren't required to run either one (i.e. get rid of storybook for size comparison)

commented

Yes, I know. That's discussed in the thread. My query still stands, if you read the second last post in that thread. Svelte is still 300K compared to 45K of jQuery + Bootstrap components.

Svelte is still 300K compared to 45K of jQuery + Bootstrap components.

That is the whole vendor bundle of the storybook page. It includes code from storybook, react and then sveltestrap. It's not obvious how much of that is sveltestrap. Somebody already mentioned this in the thread which makes me question why you keep repeating that 300kB is just sveltestrap

Storybookjs is a (big) React app for documentation and totally unrelated to svelte apart from them allowing svelte as a plugin. As mentioned here, svelte+sveltestrap+sapper alone compiles to like 14kb. Prob should discuss doc choice over there vs here on svelte repo.

Investigation of the cross over point using Svelte 3.24.1 shows that it is at about 120KB of component source.

Inflection Point

For reference, the entire Svelte website is less than 40KB (this is BEFORE splitting happens)

Total Project Component Sizes

You would need to bundle 3x the amount of components currently in the svelte website (no code splitting) to meet the size of similar amount of React component source + Libs

Closing as Svelte 5 makes this entire question outdated