--- tags: [DEV, VITE, performance, optimization] create time: 2026-04-18 --- # Vite 优化实践 ## 性能优化总览 ```mermaid graph TD A[Vite 性能优化] --> B[开发环境] A --> C[生产构建] A --> D[运行时优化] B --> B1[依赖预构建] B --> B2[智能缓存] B --> B3[热更新优化] C --> C1[代码分割] C --> C2[资源优化] C --> C3[构建配置] D --> D1[按需加载] D --> D2[缓存策略] D --> D3[监控分析] ``` ## 开发环境优化 ### 依赖预构建优化 #### 智能依赖识别 ```typescript import { defineConfig } from 'vite' export default defineConfig({ optimizeDeps: { // 手动指定需要预构建的依赖 include: [ 'react', 'react-dom', 'antd', 'lodash' ], // 排除不需要预构建的模块 exclude: [ // 已是 ESM 格式的包 'vue', // 开发时频繁修改的包 './src/common/*' ], // 强制重新构建 force: process.env.NODE_ENV === 'development' } }) ``` #### 预构建性能调优 ```typescript export default defineConfig({ optimizeDeps: { // esbuild 配置 esbuildOptions: { target: 'es2020', // 保持类名和函数名,便于调试 keepNames: true, // 启用打包内联 bundle: true, // 外部化某些依赖 external: ['some-large-library'] } } }) ``` ### 服务器配置优化 #### 高效的代理配置 ```typescript export default defineConfig({ server: { proxy: { // API 代理 '/api': { target: 'http://localhost:8080', changeOrigin: true, // 路径重写 rewrite: (path) => path.replace(/^\/api/, ''), // 超时设置 timeout: 30000, // 代理错误处理 configure: (proxy, _options) => { proxy.on('error', (err, _req, res) => { res.end(JSON.stringify({ error: err.message })) }) } }, // 静态资源代理 '/static': { target: 'http://localhost:9000', changeOrigin: true } } } }) ``` #### 开发服务器性能 ```typescript export default defineConfig({ server: { // 禁用自动浏览器打开 open: false, // 严格的端口模式 strictPort: false, // 仅监听 localhost host: '127.0.0.1', // HMR 配置 hmr: { // 覆盖层配置 overlay: { runtimeErrors: false, // 不显示运行时错误 errors: true, // 显示编译错误 warnings: false // 不显示警告 } }, // 文件监听优化 watch: { usePolling: false, // 禁用轮询(默认) interval: 100, // 轮询间隔 ignored: [ '**/node_modules/**', // 忽略 node_modules '**/.git/**', // 忽略 .git 目录 '**/dist/**', // 忽略构建输出 'coverage/**' // 忽略测试覆盖率 ] } } }) ``` ### 缓存策略 #### 依赖缓存优化 ```typescript export default defineConfig({ optimizeDeps: { // 缓存目录 cacheDir: 'node_modules/.vite', // 锁文件 lockfile: true, // 禁用缓存调试 // force: true } }) // 清理依赖缓存 // npm run dev -- --force ``` #### 模块缓存配置 ```typescript export default defineConfig({ build: { // 模块预加载 modulePreload: { polyfill: false, // 禁用预加载 polyfill resolveDependencies: false // 禁用依赖解析 } } }) ``` ## 生产构建优化 ### 代码分割策略 #### 智能代码分割 ```typescript export default defineConfig({ build: { rollupOptions: { output: { // 手动代码分割配置 manualChunks: (id) => { // 节点模块分割 if (id.includes('node_modules')) { if (id.includes('react')) { return 'vendor-react' } if (id.includes('antd')) { return 'vendor-ui' } if (id.includes('lodash') || id.includes('dayjs')) { return 'vendor-utils' } return 'vendor-other' } // 应用代码分割 if (id.includes('pages/')) { const pageName = id.split('/pages/')[1].split('/')[0] return `pages/${pageName}` } // 组件分割 if (id.includes('components/')) { const componentName = id.split('/components/')[1].split('/')[0] return `components/${componentName}` } } } } } }) ``` #### 按路由懒加载 ```typescript // React Router 懒加载示例 import { lazy, Suspense } from 'react' // 路由组件懒加载 const HomePage = lazy(() => import(/* webpackChunkName: "home" */ '@/pages/Home')) const AboutPage = lazy(() => import(/* webpackChunkName: "about" */ '@/pages/About')) const DashboardPage = lazy(() => import(/* webpackChunkName: "dashboard" */ '@/pages/Dashboard')) // 使用 Suspense 包裹 function App() { return ( Loading...}> } /> } /> } /> ) } ``` ### 资源优化 #### CSS 代码分割 ```typescript export default defineConfig({ build: { cssCodeSplit: true, // 启用 CSS 代码分割 cssTarget: 'chrome80', // CSS 目标浏览器 cssMinify: 'lightningcss' // CSS 压缩器 }, css: { devSourcemap: false, // 开发环境不生成 Source Map // PostCSS 配置 postcss: './postcss.config.js', preprocessorOptions: { scss: { api: 'modern-compiler' // 使用现代编译器 } } } }) ``` #### 静态资源优化 ```typescript export default defineConfig({ build: { // 资源处理 assetsInlineLimit: 4096, // 小于 4kb 的资源内联 rollupOptions: { output: { // 资源文件命名 assetFileNames: (assetInfo) => { const info = assetInfo.name?.split('.') ?? [] const extType = info[info.length - 1] if (/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/i.test(assetInfo.name ?? '')) { return `media/[name]-[hash].[ext]` } if (/\.(png|jpe?g|gif|svg|webp|avif)(\?.*)?$/i.test(assetInfo.name ?? '')) { return `images/[name]-[hash].[ext]` } if (/\.(woff2?|eot|ttf|otf)(\?.*)?$/i.test(assetInfo.name ?? '')) { return `fonts/[name]-[hash].[ext]` } return `assets/[name]-[hash].[ext]` } } } } }) ``` ### 压缩与优化 #### 代码压缩配置 ```typescript export default defineConfig({ build: { minify: 'terser', // 压缩器选择: terser | esbuild terserOptions: { compress: { // 移除 console drop_console: true, drop_debugger: true, // 纯函数优化 pure_funcs: [ 'console.log', 'console.info', 'console.debug' ], // 代码优化 ecma: 2020, arguments: true, dead_code: true, side_effects: true }, mangle: { // 变量名混淆 toplevel: true, properties: { regex: /^_/ // 混淆以下划线开头的属性 }, keep_classnames: false, keep_fnames: false }, format: { // 保留版权注释 comments: false, // 不移除代码 preserveAnnotations: false } }, // 不显示压缩后大小 reportCompressedSize: false } }) ``` #### 构建产物分析 ```typescript import { visualizer } from 'rollup-plugin-visualizer' import { defineConfig } from 'vite' export default defineConfig({ plugins: [ visualizer({ filename: './dist/stats.html', open: true, gzipSize: true, brotliSize: true, template: 'treemap' // treemap | sunburst | network }) ] }) // 构建后分析 // npm run build ``` ## 运行时优化 ### 按需导入 #### UI 组件按需导入 ```typescript // Ant Design 按需导入 import { ConfigProvider } from 'antd' import Button from 'antd/es/button' import Input from 'antd/es/input' // 或者使用自动导入插件 import Components from 'unplugin-vue-components/vite' import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers' export default defineConfig({ plugins: [ react(), Components({ resolvers: [ AntDesignVueResolver({ importStyle: 'less' // 按需导入样式 }) ] }) ] }) ``` #### 工具库按需导入 ```typescript // 原始导入方式(导入整个库) // import _ from 'lodash' // const result = _.map(arr, (item) => item.value) // 按需导入方式 import { map } from 'lodash-es' const result = map(arr, (item) => item.value) // 或者使用 lodash-unified-plugin ``` ### 缓存策略 #### HTTP 缓存配置 ```typescript // Nginx 配置示例 location / { try_files $uri $uri/ /index.html; # 关键资源缓存策略 location ~* \.(js|css)$ { expires 1y; add_header Cache-Control "public, immutable"; } # 图片资源缓存 location ~* \.(jpg|jpeg|png|gif|webp|svg)$ { expires 6M; add_header Cache-Control "public, max-age=15552000"; } # HTML 不缓存 location ~* \.html$ { add_header Cache-Control "no-cache, no-store, must-revalidate"; } } ``` #### 浏览器缓存优化 ```typescript // 预加载关键资源 // 在 index.html 中添加 // React 应用中的预加载 const preloadComponent = (path: string) => { const link = document.createElement('link') link.rel = 'prefetch' link.href = path document.head.appendChild(link) } // 根据路由预加载 const routes = [ { path: '/dashboard', preload: () => preloadComponent('/assets/dashboard-[hash].js') } ] ``` ### 性能监控 #### 运行时性能监控 ```typescript // 性能监控工具 class PerformanceMonitor { private metrics: Map = new Map() measure(name: string, fn: () => void) { const start = performance.now() fn() const duration = performance.now() - start this.metrics.set(name, duration) // 开发环境打印性能指标 if (import.meta.env.DEV) { console.log(`[Performance] ${name}: ${duration.toFixed(2)}ms`) } } getMetrics() { return Object.fromEntries(this.metrics) } } // 使用示例 const monitor = new PerformanceMonitor() monitor.measure('app-init', () => { initializeApp() }) ``` #### 构建 time analysis ```typescript import { defineConfig } from 'vite' export default defineConfig({ build: { // 构建时间限制 chunkSizeWarningLimit: 1000, // 构建并行化 parallel: true, // 构建统计信息 reportCompressedSize: false } }) // 使用 time 命令测量构建时间 // time npm run build ``` ## 实际案例分析 ### 大型 React 项目优化 #### 问题场景 - 🔧 项目包含 200+ 组件 - 📦 构建后的 main.js 超过 2MB - 🚀 首屏加载时间 5-8 秒 #### 优化方案 ```typescript // vite.config.ts export default defineConfig({ build: { rollupOptions: { output: { manualChunks: { // 核心框架 'react-core': ['react', 'react-dom', 'react-router-dom'], // UI 组件库 'antd-core': ['antd'], 'antd-icons': ['@ant-design/icons'], // 状态管理 'state-management': ['zustand', 'immer'], // 工具库 'utils': ['lodash-es', 'dayjs', 'axios'], // 业务模块 'business-user': [/src\/modules\/user/], 'business-order': [/src\/modules\/order/], 'business-product': [/src\/modules\/product/] } } } } }) ``` #### 优化结果 - ✅ main.js 减少到 800KB - ✅ 首屏加载时间降低到 2-3 秒 - ✅ 构建时间从 3 分钟减少到 1 分钟 ### TypeScript 项目编译优化 #### 编译速度优化 ```typescript // tsconfig.json { "compilerOptions": { "incremental": true, // 增量编译 "tsBuildInfoFile": ".tsbuildinfo", "skipLibCheck": true, // 跳过类型声明文件检查 "skipDefaultLibCheck": true }, "references": [ // 项目引用 { "path": "./packages/component" } ] } ``` #### 类型检查性能 ```typescript // 按需类型检查 // .githooks/pre-commit #!/bin/bash git diff --cached --name-only | grep '\.tsx?$' | xargs npx tsc --noEmit // 或者在开发环境只检查当前文件 // IDE 配置 TypeScript Server 模式 ``` ### 组件库开发优化 #### 库模式配置 ```typescript // vite.config.ts (组件库) export default defineConfig({ build: { lib: { entry: path.resolve(__dirname, 'src/index.ts'), name: 'MyComponentLibrary', fileName: (format) => `my-component-library.${format}.js`, formats: ['es', 'umd', 'cjs'] }, rollupOptions: { // 外部化 react external: ['react', 'react-dom'], output: { globals: { react: 'React', 'react-dom': 'ReactDOM' } } }, // 压缩 minify: 'terser', sourcemap: true } }) ``` ## 监控与调试 ### 开发环境监控 ```typescript import { defineConfig } from 'vite' export default defineConfig({ plugins: [ // 性能监控插件 { name: 'performance-monitor', transform(code, id) { // 监控大文件 if (code.length > 100000) { console.warn(`[Large File] ${id}: ${code.length} bytes`) } return null } } ] }) ``` ### 生产环境调试 ```typescript // Source Map 配置 export default defineConfig({ build: { sourcemap: true, // 生产环境生成 Source Map sourceMapDebug: false } }) // 部署环境配置错误的 Source Map // 设置为 true 便于问题追踪,false 提高安全性 ``` ## 最佳实践总结 ### ✅ 推荐实践 1. **依赖管理** - 使用 `include` 明确指定预构建依赖 - 定期清理依赖缓存 - 优先选择 ESM 格式的包 2. **代码组织** - 按路由和功能模块进行代码分割 - 使用动态导入实现懒加载 - 合理组织组件和工具函数 3. **性能优化** - 启用 Tree-shaking 移除死代码 - 使用现代压缩工具 - 优化资源加载策略 4. **监控分析** - 定期分析构建产物 - 监控应用运行性能 - 持续优化配置 ### ❌ 避免问题 1. **过度配置** - 不要过度使用配置插件 - 避免不必要的依赖 - 保持配置简洁 2. **忽略缓存** - 不要忽略依赖缓存的清理 - 注意缓存失效策略 - 合理配置缓存时间 3. **盲目优化** - 不要在没有性能问题时过度优化 - 优先解决真正的性能瓶颈 - 基于数据驱动的优化决策 ## 工具推荐 ### 构建分析工具 - **vite-bundle-visualizer** - 构建产物可视化 - **rollup-plugin-visualizer** - 深度构建分析 - **source-map-explorer** - Source Map 分析 ### 性能测试工具 - **Lighthouse** - 页面性能评估 - **WebPageTest** - 多地性能测试 - **Chrome DevTools Performance** - 运行时性能分析 优化是一个持续的过程,需要根据项目的具体情况和性能数据来调整策略。通过合理的配置和分析工具,可以让 Vite 项目在各种场景下表现优异。 相关文档: - [[DEV/VITE/配置详解.md]] - 详细配置说明 - [[DEV/VITE/架构原理.md]] - 理解优化原理 - [[DEV/VITE/README.md]] - 快速入门指南