Optimizing Vite Build Performance: A Practical Guide
Static File Chunking by Type
Configure the build options to organize output files by their type:
build: {
rollupOptions: {
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
}
}
}
This separation keeps JavaScript, CSS, fonts, and other assets in distinct directories, simplifying server configuration and CDN caching strategies.
Code Splitting for Large Resources
Approach 1: Explicit Bundlle Groups
Define specific vendor chunks in the output configuration:
manualChunks: {
vue: ['vue', 'vue-router'],
echarts: ['echarts'],
lodash: ['lodash'],
uiComponents: ['src/components/HelloWorld.vue', 'src/components/HelloWorld1.vue'],
}
Approach 2: Automatic Module-Based Splitting
For finer-grained vendor separation, dynamically split by module origin:
manualChunks(id) {
if (id.includes('node_modules')) {
const parts = id.toString().split('node_modules/')[1].split('/');
return parts[0].toString();
}
}
This approach creates a separate chunk for each third-party package, enabling better long-term caching since packages udpate at different frequencies.
Gzip Compression
Client-Side Compression
Install and configure the compression plugin:
npm i vite-plugin-compression -D
import viteCompression from 'vite-plugin-compression'
export default {
plugins: [
viteCompression({
verbose: true,
disable: false,
threshold: 10240,
algorithm: 'gzip',
ext: '.gz',
})
]
}
Configure your web server to serve pre-compressed files:
gzip_static on;
Server-Side Compression
Alternatively, enable on-the-fly compression in nginx:
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";
Comparison
Client-side compression reduces server CPU overhead at the cost of slightly larger build artifacts. Pre-compressed files are served directly, and only the browser needs to decompress them—a worthwhile trade-off for high-traffic applications.
Removing Development Code
Strip console statements and debugger breakpoints during production builds:
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
This reduces bundle size and prevents sensitive logging from reaching production.
Vite vs Webpack: Performance Considerations
Startup Time
Webpack must analyze and build the entire application graph before serving any requests. For substantial projects, this means waiting several minutes for the dev server to start, with hot updates still taking seconds.
Vite takes a different approach by categorizing modules into dependencies and source code. Dependencies go through esbuild's rapid bundling process during pre-bundling. Source code—your Vue components and TypeScript files—remains in ES module format, allowing browsers to parse them directly. Dynamic imports and route-based lazy loading further accelerate startup since resources load only when needed.
Hot Module Replacement
Webpack's HMR propagates changes through the module graph, which slows as applications grow. Vite's HMR operates at the native ESM level, invalidating only the changed module and its HMR boundary.
Vite also leverages HTTP caching intelligently: source modules use conditional requests (304 Not Modified), while dependencies receive strong cache headers (Cache-Control: max-age=31536000,immutable). This means cached dependencies never trigger re-downloads, keeping the dev experience consistently fast.