Performance
UI library bundle size: what the docs don't tell you
The number on a library's site isn't the cost in your project. Here is what really weighs, how to measure it and the five questions to ask before choosing.
Key points
- Measure your page bundle, not the npm package.
- Icons, dates, motion and charts are often heavier than the component.
- Tree shaking and targeted imports matter more than the number of components on offer.
A library can call itself lightweight and still add 80 KB to your project. The number that counts isn't the package size: it's what reaches the browser after tree shaking, with your imports and your polyfills.
What really weighs
- React and React DOM: the base, almost always shared.
- Icons: a whole set imported by mistake can outweigh the component.
- Motion: an animation library weighs more than a CSS transition.
- Dates: formatting and time zones are a hidden cost.
- Charts: one dashboard can account for half the bundle.
How to measure it
Start from the production build, not the dev server. Look at the chunks, the gzip size and the cost per route. Then repeat after removing a dependency: if the number doesn't move, that wasn't the cause.
npm run build
npx vite-bundle-visualizer
# oppure
npx source-map-explorer dist/assets/*.js
The EneUI case
The entry bundle of the EneUI home page is roughly 137.9 KB minified and 43.2 KB gzip today, with React in a separate vendor chunk. We chose to inline web-vitals instead of loading it as a separate request: 4.6 KB more in the bundle, one request less in the dependency tree.
It is an example of the real trade-off: the smallest number isn't always the fastest page. Request chain, cache, parsing and execution all count.
The five questions for the vendor
| Question | Why |
|---|---|
| Is the component tree-shakable? | One import can drag in the whole library |
| Are the icons included? | They are often the real weight |
| How many transitive dependencies? | The cost isn't in the main package.json |
| What is the cost per route, not per package? | The browser pays for the bundle, not npm |
| Is there a version without JS? | For content and SEO, the markup has to exist |
To start from a component that is already measured, open the catalogue and check the dependencies and licence on the record.
Frequently asked questions
How much should a UI library weigh?
There is no single threshold. A marketing page should stay under a few hundred KB of JS; a dashboard can carry more. Measure the route, not the package.
Is gzip the right number?
It is the number that travels over the network. Parsing and the module count also drive execution cost.
Do icons really matter?
Yes. A set imported in bulk can weigh more than the component you use. Import only the icons you need.
CSS or JS for animations?
CSS for simple transitions. For orchestration, gestures and shared layout, a JS library can be worth the cost.
How do I cut the bundle without rewriting everything?
Start from the routes, remove unused imports, check the icons and replace one dependency at a time, measuring the result.