Vite打包优化实践:从分包到性能提升

前言

随着前端应用功能的增加,项目的打包体积也会不断膨胀,影响加载速度和用户体验。本文介绍了几种常见的打包优化策略,通过Vite和相关插件,帮助减少项目体积、提升性能,优化加载速度。

rollup-plugin-visualizer

rollup-plugin-visualizer插件,是一个可视化工具,以图表的形式,展示打包结果的模块构成与体积分布。

安装:

bash 复制代码
pnpm add rollup-plugin-visualizer -D

用法:

js 复制代码
// vite.config.ts

import { visualizer } from "rollup-plugin-visualizer";

module.exports = {
  plugins: [visualizer()],
};

pnpm build 一下, 打开生成的stats.html文件。

xlsxhtml2canvasjspdf,这3个第三方库占了主要部分。

分包策略

在项目中,xlsx html2canvasjspdf,只在对应功能模块中使用,可以单独打包出来,用户使用对应功能,才会下载对应js脚本。

rollupOptions 选项的 manualChunks函数中控制分包逻辑,并配合 experimentalMinChunkSize 属性,阀值设置为 20 KB,模块大小,大于20kb的才会单独打包成chunk。

js 复制代码
rollupOptions: {
  experimentalLogSideEffects: true,
  output: {
    experimentalMinChunkSize: 20 * 1024,
    manualChunks: (id: string) => {
      if (id.includes('html2canvas')) {
        return 'html2canvas';
      }
      if (id.includes('jspdf')) {
        return 'jspdf';
      }
      if (id.includes('xlsx')) {
        return 'xlsx';
      }
    }
  }
}

build一下,查看控制台信息。 成功的将这3个第三方库单独打包成chunkvite默认会把所有静态资源都打包到assets文件夹,配置chunkFileNamesentryFileNamesassetFileNames将静态资源分类。

js 复制代码
	chunkFileNames: 'static/js/[name]-[hash].js', // 代码分割后文件名
	entryFileNames: 'static/js/[name]-[hash:6].js', // 入口文件名
  assetFileNames: 'static/[ext]/[name]-[hash].[ext]' // 静态资源文件名

build一下,打包后到结果:

减少包体积

vite-plugin-remove-console移除consele

安装:

bash 复制代码
pnpm add vite-plugin-remove-console -D

用法:

ts 复制代码
// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import removeConsole from "vite-plugin-remove-console";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), removeConsole()]
});

vite-plugin-compression压缩代码

vite-plugin-compression插件压缩代码成gzip格式或者br格式,ngixn开启gizp,http缓存策略。

安装:

bash 复制代码
pnpm add vite-plugin-compression -D

配置说明

参数 类型 默认值 说明
verbose boolean true 是否在控制台输出压缩结果
filter RegExp or (file: string) => boolean DefaultFilter 指定哪些资源不压缩
disable boolean false 是否禁用
threshold number - 体积大于 threshold 才会被压缩,单位 b
algorithm string gzip 压缩算法,可选 [ 'gzip' , 'brotliCompress' ,'deflate' , 'deflateRaw']
ext string .gz 生成的压缩包后缀
compressionOptions object - 对应的压缩算法的参数
deleteOriginFile boolean - 压缩后是否删除源文件

用法:

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

export default () => {
  return {
    plugins: [ 
      viteCompression({
        threshold: 1024 * 20, 
        algorithm: 'gzip',
        ext: '.gz'
      })]
  };
};

build一下:

修改压缩算法,打包成br格式:

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

export default () => {
  return {
    plugins: [ 
      viteCompression({
        threshold: 1024 * 20, 
        algorithm: 'brotliCompress',
        ext: '.br'
      })]
  };
};

打包结果:

br格式,明显比gzip格式还小。

外链CDN

如果条件允许外链接CDN,那么使用rollup-plugin-external-globals 插件将外部依赖映射为全局变量,避免将其打包进最终文件,减小文件体积。配合vite-plugin-html 自动注入代码到HTML文件中。

安装:

bash 复制代码
pnpm add vite-plugin-html rollup-plugin-external-globals -D

用法

js 复制代码
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { createHtmlPlugin } from 'vite-plugin-html';
import externalGlobals from 'rollup-plugin-external-globals';

const cdn = {
  jspdf: 'jspdf',
  xlsx: 'XLSX',
  html2canvas: 'html2canvas'
};

const externalList = Object.keys(cdn);

const globals = externalGlobals(cdn);

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    createHtmlPlugin({
      minify: true,
      inject: {
        data: {
          jspdfscript:
            '<script src="https://cdn.jsdelivr.net/npm/jspdf@2.5.1/dist/jspdf.umd.min.js"></script>',
          xlsxscript:
            '<script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script>',
          html2canvasscript:
            '<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>'
        }
      }
    })
  ],
  build: {
    rollupOptions: {
      external: externalList,
      plugins: [visualizer({ open: true }), globals]
    }
  }
});

index.html中使用CDN脚本:

html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AIChat</title>
    <%- xlsxscript %> <%- jspdfscript %> <%- html2canvasscript %>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

对比效果:

优化前:1.7MB

优化后:899KB

总结

本文介绍了几种优化策略:

  1. 可视化分析 :使用 rollup-plugin-visualizer 直观查看打包后的模块大小,找出大体积模块进行优化。
  2. 分包策略 :通过 manualChunks 将大依赖库分离到单独的chunk,减少首屏加载资源。
  3. 去除无用 console :利用 vite-plugin-remove-console 删除开发环境中的console,减少打包体积。
  4. 代码压缩 :通过 vite-plugin-compression 压缩代码为 gzipbrotli 格式,减小文件大小。
  5. 外链CDN :使用 rollup-plugin-external-globalsvite-plugin-html 将常用库通过CDN加载,避免将它们打包到最终文件。

这些优化策略成功将打包体积从1.7MB减少到899KB,提升了应用性能。

相关推荐
崔庆才丨静觅12 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606113 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了13 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅13 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅14 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅14 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment14 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅14 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊15 小时前
jwt介绍
前端
爱敲代码的小鱼15 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax