Vite配置实战:从零搭建高效前端开发环境

公孙诗晴 前端 阅读 2,210
赞 19 收藏
二维码
手机扫码查看
反馈

优化前:卡得不行

上周重构一个中后台项目,用的是 Vite 4 + Vue 3。本地开发跑起来还行,但一部署到测试环境,首页加载直接卡成PPT——首屏白屏5秒多,用户反馈“是不是挂了”。我点开控制台一看,bundle 包快 8MB,光 vendor.js 就占了 6MB,而且还有十几个动态 import 的 chunk,瀑布流拉得老长。最离谱的是,每次改一行代码,HMR 热更新要等 3 秒,开发体验差到想砸键盘。

Vite配置实战:从零搭建高效前端开发环境

找到瓶颈了!

先别急着改配置,得先搞清楚问题出在哪。我用了两个工具:

  • Bundle Analyzer:装个 rollup-plugin-visualizer,跑 build 时生成依赖图谱,一眼看出 lodash、moment、echarts 全被打包进 vendor,其实只用了几个函数。
  • Chrome DevTools Performance 面板:录一次加载,发现主线程被大量 script evaluation 占满,尤其是解析大 JS 文件那块,CPU 直接飙到 100%。

结论很明确:首屏资源太大,且没做合理拆分。Vite 虽然快,但默认配置对大型项目不够友好,尤其当项目里塞了各种重型库的时候。

核心优化:拆包 + 预加载 + 缓存策略

折腾了两天,试了几种方案,最后这套组合拳效果最好。

1. 手动拆分 vendor,别让 Vite 自作主张

Vite 默认会把 node_modules 里所有东西打包进 vendor,但像 echarts、xlsx 这种大库,其实只在特定页面用。我手动把它们拆出来,按需加载。

优化前的配置(啥都没配,全靠默认):

// vite.config.js
export default defineConfig({
  plugins: [vue()],
})

优化后,用 build.rollupOptions.output.manualChunks 精细控制:

// vite.config.js
export default defineConfig({
  plugins: [vue()],
  build: {
    rollupOptions: {
      output: {
        manualChunks(id) {
          if (id.includes('node_modules')) {
            if (id.includes('echarts')) {
              return 'echarts';
            }
            if (id.includes('xlsx')) {
              return 'xlsx';
            }
            if (id.includes('lodash')) {
              return 'lodash';
            }
            // 其他公共库可继续拆
            return 'vendor';
          }
        }
      }
    }
  }
})

这样 build 出来,echarts.js、xlsx.js 都是独立 chunk,只有进到报表页才加载,首页体积立马减了 2MB。

2. 预加载关键资源,别等用户点击才加载

拆完包后,虽然首屏小了,但切换到报表页时,echarts 加载又卡一下。这时候用 <link rel="prefetch">preload 提前加载。

但注意:prefetch 是空闲时加载,preload 是立即加载,别乱用。我只对首屏之后**极大概率会访问**的页面做 preload。

在入口 HTML 里加:

<!-- index.html -->
<link rel="preload" as="script" href="/assets/echarts-xxxx.js" />

或者用动态 import + webpackPrefetch 注释(Vite 也支持):

// 在路由文件中
const ReportPage = () => import(/* webpackPreload: true */ '@/views/Report.vue')

实测报表页打开速度从 1.2s 降到 300ms,因为 JS 已经在后台预加载好了。

3. 启用持久缓存,别让用户重复下载

之前每次发版,所有 JS 文件名不变,浏览器缓存失效,用户得重新下 8MB。Vite 默认会加 hash,但得确保服务器正确配置缓存头。

build 后的文件名类似 index.abc123.js,只要内容不变,hash 就不变。所以 Nginx 配置加上:

location /assets/ {
  expires 1y;
  add_header Cache-Control "public, immutable";
}

这样用户第二次访问,所有静态资源直接走 disk cache,加载时间从 5s+ 降到 800ms 以内(主要是 API 请求时间)。

其他小优化(带过)

  • 关闭 sourcemap:生产环境别开 build.sourcemap = false,能省几百 KB。
  • 压缩图片:用 vite-plugin-imagemin 自动压缩,但注意别过度压缩导致失真。
  • Tree-shaking 检查:确保用 ES Module 引入,比如 import { debounce } from 'lodash-es' 而不是 import _ from 'lodash',否则整个 lodash 都会被打包。

这里注意我踩过好几次坑:有些 UI 库(比如某 Element Plus)默认导出的是 CJS,得手动配置 resolve.alias 指向 esm 版本,否则 tree-shaking 无效。

性能数据对比

优化前后实测数据(同一台测试机,Chrome 无痕模式):

  • 首屏加载时间:5.2s → 780ms(Lighthouse 评分从 42 → 89)
  • 主包体积:8.1MB → 2.3MB(gzip 后)
  • HMR 热更新:3.1s → 400ms(开发体验飞起)

最爽的是,现在改代码几乎秒级热更新,再也不用盯着转圈圈的 logo 发呆了。

还有点小遗憾

虽然整体流畅多了,但有个小问题没彻底解决:首次加载时,如果网络慢,loading 动画会闪一下(因为 CSS 还没加载完)。理论上可以用 inline critical CSS 解决,但项目里 CSS 量不大,优先级不高,就先放着了。毕竟优化不是追求完美,而是解决最痛的点。

以上是我这次 Vite 配置优化的实战经验,核心就是三点:拆大包、预加载、设缓存。这个方案不是最优的(比如还可以用 code splitting + route-based chunking 更精细),但胜在简单有效,改完立刻见效。有更优的实现方式欢迎评论区交流,或者你也在 Vite 里踩过类似的坑?一起聊聊。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论