首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >从3.5s到0.8s:我的Vue 3 + Vite应用性能优化实战

从3.5s到0.8s:我的Vue 3 + Vite应用性能优化实战

原创
作者头像
大王叫我来巡山、
发布2025-08-28 14:45:42
发布2025-08-28 14:45:42
9430
举报
一、 引言:我们遇到了什么问题?

在最近的一个中后台管理系统的开发中,我们采用了 Vue 3 + TypeScript + Vite 这一现代技术栈。开发阶段,得益于Vite极速的热更新,体验非常丝滑。然而,在项目构建上线后,我们却收到了用户的反馈:“首页打开速度很慢,尤其是第一次访问的时候,白屏时间过长。”

通过Chrome DevTools的Lighthouse工具和Network面板进行分析,我们发现了几个核心问题:

  1. 首屏加载时间长达3.5秒
  2. 首屏JavaScript资源体积过大(~1.2MB),其中包含了大量未拆包、未按需加载的模块。
  3. 第三方依赖(如element-plus, lodash-es) 未做有效Tree Shaking和CDN优化

这显然无法令人接受。于是,我们开启了一场针对性的性能优化之旅。

二、 核心优化思路与操作步骤

我们的优化围绕一个核心原则:尽可能减少首屏需要加载和解析执行的资源量

1. 路由懒加载:按需加载代码块(Code Splitting)

场景:我们的项目有几十个路由页面,如果全部打包到一个文件中,首加载体积必然巨大。

操作:Vue Router天然支持动态导入,Webpack和Vite都会自动将其识别为代码分割点。

关键代码(优化前 vs 优化后):

代码语言:javascript
复制
// 优化前:静态导入,所有页面打包到一个chunk中
import Home from '@/views/Home.vue'
import UserList from '@/views/UserList.vue'

const routes = [
  { path: '/', component: Home },
  { path: '/users', component: UserList }
]
代码语言:javascript
复制
// 优化后:使用动态导入,生成单独的chunk
const routes = [
  {
    path: '/',
    component: () => import('@/views/Home.vue') // 会产生一个单独的chunk
  },
  {
    path: '/users',
    component: () => import('@/views/UserList.vue') // 会产生另一个单独的chunk
  }
]

效果:现在,只有用户访问特定路由时,才会加载对应页面的JavaScript代码。首屏只需要加载Home.vue相关的代码,体积瞬间减小。


2. 依赖包拆包与Tree Shaking(Vite Rollup配置)

场景:即使做了路由懒加载,首屏主包(index.[hash].js)依然很大,因为它包含了所有初始依赖的第三方库(如vue, element-plus, axios, lodash-es)。

思路:利用Vite(底层基于Rollup)的manualChunks配置,将几乎不会改变的第三方库单独打包,利用浏览器缓存机制(强缓存),用户第二次访问时就不需要再次下载这些文件了。

关键配置(vite.config.ts):

代码语言:typescript
复制
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  build: {
    rollupOptions: {
      output: {
        // 手动拆包
        manualChunks: (id) => {
          if (id.includes('node_modules')) {
            // 将第三方库拆成单独的chunk
            // 1. 将vue相关的库打包到一起
            if (id.includes('vue') || id.includes('@vue')) {
              return 'vue-vendor'
            }
            // 2. 将element-plus打包到一个 chunk
            if (id.includes('element-plus')) {
              return 'element-plus-vendor'
            }
            // 3. 其他第三方库打包到一起
            return 'vendor'
          }
        }
      }
    }
  }
})

同时,确保Tree Shaking生效

对于element-pluslodash-es,我们必须按需导入,而不是全量导入。

代码语言:typescript
复制
// 错误示例(全量导入): main.ts
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)

// 正确示例(按需导入): 1. 安装unplugin-vue-components 2. 修改vite.config.ts
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  plugins: [
    vue(),
    Components({
      resolvers: [ElementPlusResolver()], // 自动按需导入Element Plus组件
    }),
  ],
})
代码语言:javascript
复制
// lodash-es 也应使用具名导入,而不是导入整个库
// 错误示例
import _ from 'lodash-es'
_.debounce()

// 正确示例
import { debounce } from 'lodash-es'
debounce()

效果vue, element-plus等依赖被提取到独立的、可长期缓存的chunk中。同时,Tree Shaking移除了未使用的组件和函数,进一步减小了体积。


3. 压缩与Gzip(部署层优化)

场景:网络传输体积依然有优化空间。

操作:Vite开箱即用提供了资源的压缩(通过terser进行代码压缩混淆)。此外,我们可以在Nginx服务器上开启Gzip压缩,进一步减少传输体积。

Nginx配置示例(nginx.conf):

代码语言:nginx
复制
http {
    gzip on; # 开启gzip
    gzip_min_length 1k; # 大于1KB的文件才压缩
    gzip_comp_level 6; # 压缩级别(1-9),通常6是性价比最高的
    gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss; # 压缩类型
    gzip_vary on;
}

效果:我们的JavaScript文件在网络传输中的体积减少了60%-70%。

三、 优化成果与数据对比

优化前后,我们使用 npm run build 打包并通过Lighthouse进行分析,对比如下:

指标

优化前

优化后

提升

首屏加载时间

~3500ms

~800ms

77%

最大内容绘制 (LCP)

3.2s

1.1s

65%

打包总体积

~3.2MB

~1.5MB

53%

首屏主包体积

~1.2MB

~350KB

71%

四、 总结与思考

这次优化实践让我深刻体会到,性能优化是一个系统工程,需要从代码组织构建工具配置部署环境三个层面共同发力。

  1. 代码层面:养成好习惯,如使用路由懒加载、第三方库按需引入,是从源头解决问题。
  2. 构建工具层面:深入了解所使用的工具(如Vite/Rollup/Webpack)的配置项至关重要。manualChunksTree Shaking等功能是优化打包结果的利器。
  3. 部署层面:Gzip、CDN、HTTP/2等技术的合理运用,能为最终用户体验带来最后一公里的提升。

下一步,我们还可以考虑:

  • 使用vite-plugin-pwa为应用添加PWA特性,利用Service Worker实现缓存和离线访问。
  • 分析打包产物(使用rollup-plugin-visualizer),进一步找出可优化的依赖项。

希望这篇实战记录能对你的项目有所帮助!如果你有更好的优化方案,欢迎在评论区交流。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、 引言:我们遇到了什么问题?
  • 二、 核心优化思路与操作步骤
    • 1. 路由懒加载:按需加载代码块(Code Splitting)
    • 2. 依赖包拆包与Tree Shaking(Vite Rollup配置)
    • 3. 压缩与Gzip(部署层优化)
  • 三、 优化成果与数据对比
  • 四、 总结与思考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档