Vue3 + Vite4 项目的性能优化配置方案

一、基础性能优化配置(vite.config.ts)

1. Gzip 压缩加速

typescript 复制代码
import viteCompression from 'vite-plugin-compression';

// plugins 数组中添加
viteCompression({
  verbose: true, // 显示压缩日志
  threshold: 10240, // 超过10kb的文件才压缩
  algorithm: 'gzip', // 算法可选brotliCompress
  ext: '.gz',
  deleteOriginFile: false // 根据服务器配置决定是否删除源文件
})

作用 :预生成.gz文件,Nginx等服务器直接发送压缩包
业务场景

  • 高并发场景建议开启(需服务器配合)
  • 静态资源托管CDN时建议删除源文件(deleteOriginFile: true

2. 资源压缩优化

typescript 复制代码
import { viteStaticCopy } from 'vite-plugin-static-copy';

// 图片压缩(需安装 vite-plugin-imagemin)
import viteImagemin from 'vite-plugin-imagemin';

export default {
  plugins: [
    viteImagemin({
      gifsicle: { optimizationLevel: 7 },
      optipng: { optimizationLevel: 7 },
      mozjpeg: { quality: 65 },
      pngquant: { quality: [0.65, 0.9] },
      svgo: {
        plugins: [{ name: 'removeViewBox' }, { name: 'cleanupIDs' }]
      }
    }),
    // 静态资源复制插件
    viteStaticCopy({
      targets: [
        { src: 'public/static-assets', dest: 'assets' }
      ]
    })
  ]
}

作用

  • 图片压缩:降低图片体积(适合中大型图片资源项目)
  • 静态资源分类:通过viteStaticCopy分离高频更新资源

业务场景

  • 图片为主的展示型网站必须开启
  • 管理后台类项目可酌情降低压缩率(quality: 75

3. 分包策略

typescript 复制代码
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks: (id) => {
          if (id.includes('node_modules')) {
            if (id.includes('vue')) return 'vue-core';
            if (id.includes('lodash')) return 'lodash';
            return 'vendor';
          }
          if (id.includes('src/components')) return 'components';
        },
        chunkFileNames: 'js/[name]-[hash].js'
      }
    }
  }
}

分包规则

  • vue-core:Vue核心库单独分包
  • vendor:第三方依赖包
  • components:业务组件独立分包

业务场景

  • 多入口应用:按路由入口分包
  • 组件库项目:按功能模块分包

4. 按需加载

typescript 复制代码
// 路由配置示例
const routes = [
  {
    path: '/dashboard',
    component: () => import(/* webpackChunkName: "dashboard" */ '@/views/Dashboard.vue')
  }
]

实现方式

  • 路由级:动态import()语法

  • 组件级:defineAsyncComponent

  • UI库按需加载(以Element Plus为例):

    typescript 复制代码
    import Components from 'unplugin-vue-components/vite'
    import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
    
    Components({
      resolvers: [ElementPlusResolver()],
      dts: true // 生成类型声明文件
    })

5. 热更新配置

typescript 复制代码
export default {
  server: {
    hmr: {
      overlay: true, // 显示错误覆盖层
      protocol: 'ws',
      host: 'localhost',
      port: 3000
    },
    watch: {
      usePolling: true // Docker环境需要开启
    }
  }
}

调试技巧

  • 开发环境禁用缓存:server.headers设置Cache-Control: no-store
  • 跨设备开发:设置host: '0.0.0.0'

6. 路径别名配置

typescript 复制代码
import path from 'path';

export default {
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
      '#': path.resolve(__dirname, './types')
    }
  }
}

配套设置

json 复制代码
// tsconfig.json
{
  "compilerOptions": {
    "paths": {
      "@/*": ["./src/*"],
      "#/*": ["./types/*"]
    }
  }
}

7. Sourcemap 策略

typescript 复制代码
export default {
  build: {
    sourcemap: process.env.NODE_ENV === 'production' ? 'hidden' : true
  }
}

模式说明

  • 开发环境:完整sourcemap
  • 生产环境:hidden-source-map(仅生成.map文件不上传)
  • 错误监控:接入Sentry时需开启sourcemap上传

二、进阶优化方案

1. CDN 加速

typescript 复制代码
import { createHtmlPlugin } from 'vite-plugin-html';

export default {
  plugins: [
    createHtmlPlugin({
      inject: {
        data: {
          cdnVue: '<script src="https://cdn.jsdelivr.net/npm/vue@3"></script>'
        }
      }
    })
  ],
  build: {
    rollupOptions: {
      external: ['vue', 'vue-router'],
      output: {
        globals: {
          vue: 'Vue',
          'vue-router': 'VueRouter'
        }
      }
    }
  }
}

2. 预加载优化

typescript 复制代码
// vite.config.ts
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          // ...其他配置
        },
        assetFileNames: 'assets/[ext]/[name]-[hash][extname]'
      }
    }
  }
}

// index.html 添加预加载
<link rel="preload" href="/assets/fonts/iconfont.woff2" as="font" type="font/woff2" crossorigin>

三、业务场景配置策略

场景1:高并发门户网站

typescript 复制代码
// 配置重点:
1. 开启Gzip + Brotli双重压缩
2. 所有静态资源上传CDN
3. 使用HTTP2服务器推送
4. 配置强缓存策略(Cache-Control: public, max-age=31536000)

// 示例配置:
build: {
  assetsInlineLimit: 4096, // 4kb以下资源转base64
}

场景2:后台管理系统

typescript 复制代码
// 配置重点:
1. 按功能模块分包
2. 保留详细sourcemap便于调试
3. 开发环境优化HMR速度

// 示例配置:
server: {
  watch: {
    ignored: ['!**/node_modules/your-package/**'] // 忽略无关模块监听
  }
}

场景3:移动端H5应用

typescript 复制代码
// 配置重点:
1. 首屏资源内联(critical CSS)
2. 图片格式优先使用WebP
3. 开启SSR或预渲染

// 示例配置:
css: {
  postcss: {
    plugins: [
      require('postcss-critical-css')({
        outputPath: 'critical'
      })
    ]
  }
}

四、调试与分析工具

  1. 打包分析
bash 复制代码
npm install rollup-plugin-visualizer -D

// vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer';

plugins: [visualizer({ open: true })]
  1. 性能检测
javascript 复制代码
// main.ts
import { performance } from 'perf_hooks';
if (import.meta.env.DEV) {
  performance.mark('app-start');
}

五、注意事项

  1. 压缩兼容性

    • 确保服务器正确配置Content-Encoding响应头
    • 旧版浏览器需检测是否支持Brotli
  2. 缓存策略

    • 修改文件名哈希规则(build.rollupOptions.output.[assetFileNames|entryFileNames]
    • 使用manifest.json管理版本号
  3. 安全优化

    • 生产环境禁用sourcemap
    • 设置build.minify: 'terser'并配置混淆参数
相关推荐
拾光拾趣录3 分钟前
for..in 和 Object.keys 的区别:从“遍历对象属性的坑”说起
前端·javascript
OpenTiny社区14 分钟前
把 SearchBox 塞进项目,搜索转化率怒涨 400%?
前端·vue.js·github
编程猪猪侠43 分钟前
Tailwind CSS 自定义工具类与主题配置指南
前端·css
qhd吴飞1 小时前
mybatis 差异更新法
java·前端·mybatis
YGY Webgis糕手之路1 小时前
OpenLayers 快速入门(九)Extent 介绍
前端·经验分享·笔记·vue·web
患得患失9491 小时前
【前端】【vueDevTools】使用 vueDevTools 插件并修改默认打开编辑器
前端·编辑器
ReturnTrue8681 小时前
Vue路由状态持久化方案,优雅实现记住表单历史搜索记录!
前端·vue.js
UncleKyrie1 小时前
一个浏览器插件帮你查看Figma设计稿代码图片和转码
前端
遂心_1 小时前
深入解析前后端分离中的 /api 设计:从路由到代理的完整指南
前端·javascript·api
你听得到111 小时前
Flutter - 手搓一个日历组件,集成单日选择、日期范围选择、国际化、农历和节气显示
前端·flutter·架构