Analyze and optimize your Vite bundle
It is important to analyze your bundle generated by Vite from time to time, as often there will be some low-hanging opportunities to reduce its size. In this post I will show you how to analyze and optimize your Vite bundle by removing duplicate code and packages.
Analyze your Vite bundle
I have been using vite-bundle-visualizer
in the past. It does what it says in the box and visualize my bundle, but I still have to spend time on examining charts and figure out what issues does my bundle contain.
I think rollup-plugin-bundle-stats
addressed my pain point here, and it is a superior option to analyze your Vite bundle. It gives me a clear pointer on duplicate code and packages, so I can address them easily. As Vite uses Rollup for bundling, we can use this plugin with Vite as well. You can install this package with whatever package manager you want.
npm i rollup-plugin-bundle-stats -D
After installing this package, you need to add this plugin to your Vite configuration. Even though all options for this plugin is optional, it cannot find the baseline.json
in my SvelteKit project out of the box, and I have to set the path manually at baselineFilePath
. I have also set silent: true
to reduce the log output from this plugin.
import { defineConfig } from 'vite';
import { bundleStats } from 'rollup-plugin-bundle-stats';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
const currentDir = dirname(fileURLToPath(import.meta.url))
export default defineConfig({
plugins: [
bundleStats({
baselineFilepath: join(currentDir, "node_modules", ".cache", "bundle-stats", "baseline.json"),
silent: true,
}),
],
});
Then you can run vite build
to build your project and generate the package analysis. You should be able to find a bundle-stats.html
in the output directory of vite build
.
Remove duplicate packages from your bundle
To walk you through the process of removing duplicate packages from your bundle, I have created a minimal SvelteKit project with @grafana/faro-rollup-plugin
, @grafana/faro-web-sdk
and @grafana/faro-web-tracing
installed. These packages have some shared and duplicated dependencies, and it is perfect for demonstration.
Running vite build
for this project for the first time, and inspect bundle-stats.html
, we can see that there are 7 duplicate packages in this project. Click on the “duplicate packages” tab, we can see that the duplicate packages are @opentelemetry/core
, @opentelemetry/semantic-conventions
and @opentelemetry/sdk-trace-web
.
To unify the version of our packages and remove duplicate, we can define the desired version in package.json
in overrides
(or resolutions
if you are using yarn
). After updated package.json
, we then need to run npm dedupe
to update package-lock.json
and remove duplicate packages, and we can run vite build
again to verify the result. You might have to repeat this process multiple times, until you have removed all duplicate, as the new resolved packages might have duplicate dependencies with your existing packages.
A word of warning, overriding packages’ version with overrides
might break your project. It is better to write some tests beforehand to verify features of your project is still intact.
{
// ...
"devDependencies": {
"@grafana/faro-rollup-plugin": "^0.1.1",
"@grafana/faro-web-sdk": "^1.12.2",
"@grafana/faro-web-tracing": "^1.12.2"
},
"overrides": {
"@opentelemetry/resources": "1.27.0",
"@opentelemetry/core": "1.27.0",
"@opentelemetry/semantic-conventions": "1.27.0",
"@opentelemetry/sdk-trace-web": "1.27.0"
}
}
At the end, we could see that all duplicate packages are gone, and the bundle size decreased slightly as well. With a bigger project, you should see greater changes.