top | item 45734236

(no title)

simjnd | 4 months ago

> You're not answering my question, just adding some more feelings.

Well you seemed surprised by this fact, even though it's a given for most people working in front-end frameworks.

> React is < 10 kb compressed https://bundlephobia.com/package/react@19.2.0 (add react-dom to it).

I don't know how bundlephobia calculates package size, and let me know if you're able to reproduce them in a real app. The simplest Vite + React app with only a single "Hello, World" div and no dependencies (other than react and react-dom), no hooks used, ships 60+ kB of JS to the browser (when built for production, minified and gzipped).

Now the blog post is not just using React but Next.js which will ship even more JS because it will include a router and other things that are not a part of React itself (which is just the component framework). There are leaner and more performant React Meta-Frameworks than Next.js (Remix, TanStack Start).

> This is not kilobytes or initial render times, but performance in rendering in a highly interactive application

True, but it's another area where React is a (relative) catastrophe.

The large bundle size on the other hand will definitely impact initial render times (in client-side rendering) and time-to-interactive (in SSR), because it's so much more JS that has to be parsed and executed for the runtime before even executing your app's code.

EDIT: It also does not have to be a highly interactive application at all for this to apply. If you only change a single value, that is read in a component deep within a component tree you will definitely feel the difference, because that entire component tree is going to execute again (even though the resulting diff will show that only that deeply nested div needs to be updated, React has no way of knowing that beforehand, whereas signal-based framework do)

And finally I want to say I'm not a React hater. It's totally possible to get fast enough performance out of React. There are just more footguns to be aware of.

discuss

order

acemarke|4 months ago

React's bundling system and published packages has gotten noticeably more complicated over time.

First, there's the separation between the generic cross-platform `react` package, and the platform-specific reconcilers like `react-dom` and `react-native. All the actual "React" logic is built into the reconciler packages (ie, each contains a complete copy of the actual `react-reconciler` package + all the platform-specific handling). So, bundle size has to measure both `react` and `react-dom` together.

Then, the contents of `react-dom` have changed over time. In React 18 they shifted the main entry point to be `react-dom/client`, which then ends up importing the right dev/prod artifacts (with `react-dom` still supported but deprecated):

- https://app.unpkg.com/react-dom@18.3.1/files/cjs

Then, in React 19, they restructured it further so that `react-dom` really only has a few utils, and all the logic is truly in the `react-dom/client` entry point:

- https://app.unpkg.com/react-dom@19.2.0/files/cjs/react-dom.d...

- https://app.unpkg.com/react-dom@19.2.0/files/cjs/react-dom-c...

So yes, the full prod bundle size is something like 60K min+gz, but it takes some work to see that. I don't think Bundlephobia handles it right at all - it's just automatically reading the main entry points for each package (and thus doesn't import `react-dom/client`. You can specify that with BundleJS though:

- https://bundlejs.com/?q=react%2Creact-dom%2Fclient&treeshake...

> Bundle size is 193 kB -> 60.2 kB (gzip)

maelito|4 months ago

Thanks for the detailed explanations !