Comment by oefrha
3 days ago
The bloat isn't coming from "huge frameworks" like React.
To give some concrete numbers: a barebones react project created with `pnpm create vite -t react-ts` clocks in at ~60KB compressed:
dist/index.html 0.46 kB │ gzip: 0.30 kB
dist/assets/react-CHdo91hT.svg 4.13 kB │ gzip: 2.14 kB
dist/assets/index-D8b4DHJx.css 1.39 kB │ gzip: 0.71 kB
dist/assets/index-9_sxcfan.js 188.05 kB │ gzip: 59.16 kB
A vue project (`pnpm create vite -t vue-ts`) is even smaller at ~25KB:
dist/index.html 0.46 kB │ gzip: 0.30 kB
dist/assets/index-1byZ3dr3.css 1.27 kB │ gzip: 0.65 kB
dist/assets/index-CKXNvRRZ.js 60.77 kB │ gzip: 24.44 kB
I've created plenty of medium-sized projects with React/Vue clocking in at 200-300KB compressed (excluding image assets). You can still realistically use those on 2G — yes I've tried, not just in dev tools, but when I was actually rate limited to 2G.
> When a simple home page dashboard or a notes page takes more than 10s to load on a 10G connection peered within 5ms of the host, and 95% of this is spent in JS.
You can create that kind of garbage with any framework, or without framework. You can actually do worse with the traditional way of using third party dependencies wholesale (the jQuery way), you can be downloading 200KB for 1KB of actually used code.
Edit: Also, the comparison in the article is pretty stupid. A full view in React is not much larger than "a React button", it's upfront cost + marginal cost.
Author here: Fair point—React’s baseline isn’t a monster. ~60KB compressed for a barebones Vite/React setup, or even ~25KB with Vue. Medium projects at 200-300KB are definitely workable.
But here’s the point: a single React/ShadCN button, straight from their official docs, still outweighs Nue’s entire SPA demo. Add more widgets—tabs, modals, whatever—and that gap only widens. Nue is flipping the script. Web standards let us start lean and stay lean—smaller codebases, faster HMR, quicker builds. That’s the win: efficiency that scales without piling complexity.
> a single React/ShadCN button
So don't use ShadCN? It's so weird to put up this strawman app and then be like "see what's wrong with React"? Like showing two boards nailed together and being like "can you believe I needed all those power tools just to do this?"
> Add more widgets—tabs, modals, whatever—and that gap only widens
This is the benchmark I want to see. Two full-featured apps built with minimal prod dependencies. There's a pretty good chance that the various ShadCN modules share many of their dependencies so that importing more doesn't necessarily mean a linear increase in bundle size. It could be that once you build something full-featured, React projects come in smaller, or at least not big enough to invalidate the other upsides of choosing it.
But the OP did implement a fully featured app as the Nue comparison half of the benchmark. I have never used Nue and don't know if I ever would. I just think to be fair to the OP, even if incremental cost declines as you keep adding stuff in React, there's no way it is negative, which means the benchmark you asked for logically must have a similar result?
1 reply →
> Two full-featured apps built with minimal prod dependencies.
This isn't what you see in the real world. I'd rather see comparisons to real life (where 99.9% of web apps are bloated garbage) than nonsense synthetic benchmarks like that.
3 replies →
An extra 100-200KB compressed is a ~100ms one time cost once in a while for the majority of my users, and ~1s for 95%+ of users. At that point I'm going to optimize for developer productivity (which includes breadth of ecosystem). I can be both productive and respectful to my users with these common frameworks.
Note that I'm very mindful of web performance, and I've been quite vocal on this site about some alarming trends like calling for the end of bundling (native esm) and roundtrips for everything (liveview and co., or at least the abuse of them). In my experience waterfalls and roundtrips are the number one thing hated by people on slow and/or unreliable networks; 100KB added to a flat bundle at load is almost nothing.
> An extra 100-200KB compressed is a ~100ms one time cost once in a while for the majority of my users, and ~1s for 95%+ of users. At that point I'm going to optimize for developer productivity
Is that 100ms on fiber? Cable? 5G? 4G?
Is that for the first button? Or each button? And what happens when you next need to manage dates as objects? Do you pull down dayjs or do you wrangle it yourself? What other libraries do you need to add? How's build speed? How much time to the linters take as they cascade through all that code? How are your Next.js (a pretty standard companion to react) version updates going? Keeping up with security alerts?
I'm biased against React because I manage a team trained in classic web design who now have to manage a giant React codebase and learn its special way of doing things, and it's a slog.
Agencies are going to keep building with React because they can get 90% of a project done in no time flat, and they don't have to deal with the infra challenges after they get their check. Small clients like us will continue to fall for it and slowly grind to a halt as the infrastructure pulls the team to a standstill.
8 replies →
Although payload can be indicative of page load speed, there are many good reasons Lighthouse scores are more complex than that. Specifically, at the start of this thread the criticism was that the js work in modern web apps is slow. I have thus far managed to avoid using react so I don't know the actual numbers, but I don't think the conversation should be reduced to payload size, even if it is obviously important. When I profile problematic pages, other than sites that don't properly scale their images, it is not usually network that bogs them down, it is the rendering.
Even focusing on Lighthouse score or similar for a basic app is totally missing the point of Nue as presented on the linked page. It about a framework designed for speed that can handle data at scale, that is easier to control and personalize, and easier to model and thus architect. And yes, of course, most any framework can be used for good work, but the relevant question here is which one promotes it the most from start to finish, and makes it the easiest to implement. Speaking only for myself, this focus is great to see.
How much is it React/Nue and how much is everything else?
HTML has evolved in the last 15 years to be a platform for applications. The early Bootstrap was a terrible Rube Goldberg machine because CSS didn't have civilized layout mechanisms such as grid and flexbox. Newer frameworks like Tailwind are more sensible, but still add 50k to your bundle, and if your app is complex and developed under deadlines you probably have components that use Tailwind and Bootstrap and emotion and styled-components and raw CSS and you still have to write some SCSS to get the styles just right in the end.
I've been investigating the accessibility of various <Modal> components and found that they all suck because they do complicated things with <Portal>(s) and various-aria-attributes. HTML has had a <dialog> component that properly hides the rest of the page since 2022 but barely anyone was using it.
If you stuck to using Tailwind or Bootstrap or raw CSS and used a minimal widget set you can make small applications with any framework. If you wrote raw CSS and made the most of the widgets that come in HTML5 (like the new stylable <select>) you can make tiny applications.
Tailwind, at least for the last couple major versions, only adds the classes you actually use (plus the resets). Baseline size of the resets is far below 50k.
Great point about the dialog element. I used it in a project recently for the first time... It was very nice to not involve a framework-heavy "portal" scheme, etc.
2 replies →
> React’s baseline isn’t a monster.
Yes it is. It’s not size, it’s logic: Every time the component rerenders, the root loop is executed. Why? The root loop reassigns every useEffect, reruns every useState, every other hook (and useSearchParams is executed n times for n components that need it in the hierarchy) when only the HTML needs rerender.
(Yes the programmer can optimize/memoize, and yes “a hook’s execution time is very short” (but multiplied by every cell in the table, when needed)). Must be the fault of the programmer if the framework has a super-intensive concept at the root.)
I'm old enough to remember when this simplified model was why people thought React was better than alternatives.
2 replies →
> It’s not size
That's what TFA is complaining about: size. But nice pivot, hope your head isn't spinning too much.
Yeah, react developers don’t even realize that there is execution time as well as download time for an app.
I think Nue just puts you in the mindset of trying to keep the codebase as small and lightweight as possible. I wanted to rebuild my website with Nue and there was something telling me to avoid Motion, Tailwind CSS, etc. This philosophy can actually prove very helpful in the long term, however I feel that by using Nue you're really compromising on DX (development is much slower), although that might be because I'm not so familiar with creating websites without a framework. In any case, it's definitely worth a try.
this means the example wasn't made to be lightweight. You'll need an apples to apples example to convince any detractor. Implement the same app using two different toolsets, document the process with each and then benchmark it
To be honest, I am very confused with this benchmark. It is misleading.
What is the actually size of the production build portion only for that button part? Because I think that the ShadCN button source code is not equal in size for the button that client downloads in production environment. Especially if you have SSR.
If you look at the demo, all of the payload comes from react and the tailwindcss classes that the shadcn button refers to.
It's dishonest to call this the payload of "one shadcn button" since it's basically all react/tailwindcss fixed cost and not literally a shadcn button.
But still, that's a decently broad demo to fit in a small payload, so the exaggeration kinda takes away from that.
The main thing I care about in client development is the state management solution since that's where most of the complexity comes from, and it's what makes or breaks an approach. In React, I use MobX which I see as the holy grail.
Whether Nue is nice to use or not for me is gonna come down to how nice this is to work with: https://nuejs.org/docs/interactivity.html
7 replies →
Seems like you should be correct. A shadcn button is just react, tailwind, and @radix/react-slot. But if you simply create a new shadcn Next.js template (i.e. pnpm dlx shadcn@latest init) and add a button, the "First Load JS" is ~100kB. Maybe you could blame that on Next.js bloat and we should also compare it to a Vite setup, but it's still surprising.
3 replies →
[flagged]
Some people just really like em dashes.
This sounds like ChatGPT’s voice :)
It really doesn't sound like ChatGPT’s default voice, though it is pretty good at taking on different voices so in a sense you could say that about almost anything. It does use em-dashes, which people have recently started way over-indexing on as a ChatGPT tell, but lots of posters on HN have been using em-dashes for longer than ChatGPT has existed.
It does read like marketing material, though.
4 replies →
It does, and it muddies the waters a lot. Why does it read like a sales pitch?
ChatGPT learned that voice from actual people, you know.
4 replies →
Downloading =/= executing. Downloading 60 kb of compressed JavaScript isn't the problem, the problem is running that JavaScript, and all the resulting web calls that JavaScript will do, and all the resulting compute it will take to... I dunno, make the button round or whatever. Load time is no longer a solid metric for a good experience, that's very late 00's of anyone to say, the metric now is how long until the page is laid out, and the controls on it are responsive?
Edit: Also how hot is my phone?
absolutely. page performance is the result of a hairball of initial asset loads, AJAX calls, ad-hoc roundtrips, telemetry bloat, ...
It's so convoluted, and very app specific. Core web vitals provide the right framework to think about what is relevant, but in reality your app likely requires dedicated instrumentation to capture these phases accurately.
I test my damn sites on a fucking iPhone 6 from 2014. Executing that JS is a breeze.
React etc. runs just fine on absolute garbage kiosks. If you introduce 10MB of additional JS on top of 60KB of React, it's those 10MB's fault.
Downloading 60kb of compressed javascript takes way longer than executing it.
Executing 60kb of JS can take between 0s and infinity. You can't summarise it like this.
4 replies →
> The bloat isn't coming from "huge frameworks" like React.
I agree. This is such a familiar cycle. People still blame Java for things that were really the fault of the average "enterprise Java developer".
The reality is that these frameworks don't automatically lead to bloated code shipping everything.
Isn’t using compressed numbers pretending that network bandwidth is the only cost of bloat?
All that JS, once decompressed, needs to be parsed and actually evaluated. That is where it hurts even people on gigabit connections.
I think frontend bloat has arrived at such an absurd level that it kind of makes me wish broadband and mobile speeds, and JS engine speeds, had paused their advancement for 15 years so that FE developers would have had to learn to write good code. Presently there is a whole generation of developers who built their whole careers in this era where you can get acceptably mediocre performance even with wildly inefficient code and an absurd amount of dependencies, most of them barely used on a given page. They’ve never been challenged to do any better, so i don’t really blame them.
Just to add Svelte (`pnpm create vite -t svelte-ts`) ~8KB
> You can create that kind of garbage with any framework, or without framework
I would think it would be quite a challenge to accomplish the given task without a framework?
before React took over, "SPAs" were written with jQuery and Bootstrap, and it was common to see a project with multiple copies of different versions of jQuery. Totally possible to bloat a website without a framework. just go old school!
>You can create that kind of garbage with any framework, or without framework.
The whole point of the framework is to make even absolute garbage stick together. (While making the developer replaceable.)