This isn't a comprehensive in-depth analysis but I have this SPA which is built with Vite + React.
When you run npm run build
it produces:
vite v5.4.8 building for production... ✓ 8210 modules transformed. dist/index.html 0.76 kB │ gzip: 0.43 kB dist/assets/images-xTxpPavl.css 2.02 kB │ gzip: 0.55 kB dist/assets/index-IHK6QBxo.css 200.12 kB │ gzip: 29.85 kB dist/assets/index-jgmGYYS9.js 0.79 kB │ gzip: 0.51 kB dist/assets/open-graph-image-Ca6hLYnz.js 1.47 kB │ gzip: 0.82 kB dist/assets/images-CwbhV2EW.js 28.75 kB │ gzip: 10.37 kB dist/assets/pageviews-C6NSq649.js 378.67 kB │ gzip: 106.42 kB dist/assets/index-HpyQl1NK.js 490.15 kB │ gzip: 154.11 kB ✓ built in 4.46s
So you can now host that index.html
and its .js
files on a CDN. Nice and simple.
Some of the routes within can be code-split-loaded. That means that, at runtime, when you view a certain route it realizes it needs more .js
downloaded. Vite takes care of all of these things for you.
The particular app I was working on, is using a heavy React UI library (that I love!) called Mantine. It's what makes up most of those kilobytes in the dist/assets/*.js
files. Given that that core library is shared across all routes, is there much point in code-splitting certain routes? Short answer: No.
This is what it becomes after one route becomes code-split:
dist/index.html 0.76 kB │ gzip: 0.43 kB dist/assets/index-CZBKe-ji.css 0.10 kB │ gzip: 0.12 kB dist/assets/images-xTxpPavl.css 2.02 kB │ gzip: 0.55 kB dist/assets/index-D_HkGvkF.css 200.12 kB │ gzip: 29.85 kB dist/assets/index-CPfMford.js 0.79 kB │ gzip: 0.51 kB dist/assets/open-graph-image-Ce-NyYuQ.js 1.48 kB │ gzip: 0.83 kB dist/assets/SegmentedControl-D1707s77.js 5.73 kB │ gzip: 2.40 kB dist/assets/images-BO-d0Fjs.js 28.81 kB │ gzip: 10.40 kB dist/assets/index-Dt3LhvfX.js 39.56 kB │ gzip: 13.95 kB dist/assets/pageviews-Bv5lRAmb.js 378.68 kB │ gzip: 106.42 kB dist/assets/index-CF-p0kS9.js 446.00 kB │ gzip: 140.30 kB
Can you tell the difference?
For one, there are now 3 .css
files instead of 2. And 7 .js
files instead of 5.
The total summed size goes from 1102.73 KB to 1104.05 KB.
I think the point is; it's not really about your code that you split, but about the underlying heavy libraries that it uses. So worry more about than anything.
Actually, if you look carefully, there's an asset bundle in there called dist/assets/pageviews-Bv5lRAmb.js
which is a whopping 378.68 KB. The reason for that is because I know it contains recharts
within. For that particular problem, it wasn't a matter of per-route but within the component. The code for it looks like this:
import { Container, Title } from "@mantine/core";
import { Suspense, lazy } from "react";
import type { EditBlogitemT } from "../../types";
const PageviewsInner = lazy(() => import("./pageviews"));
export function Pageviews({ blogitem }: { blogitem: EditBlogitemT }) {
return (
<Container id="analytics" mt={50}>
<Title order={3}>Pageviews</Title>
<Suspense fallback="Loading analytics">
<PageviewsInner blogitem={blogitem} />
</Suspense>
</Container>
);
}
and thankfully this is a non-critical component that is visually present in the app below the fold so there's definitely no pressing problem of slow starts on the route because it can take its time.
Comments