前端优化绕不开的那些事-vite项目打包构建优化

背景

公司管理系统按服务项目分为2部分:

  • 应用产品(CMS项目):B2C 产品的后台管理系统,主要是对直接面向用户产品内容的管理。
  • 管理产品(CRM项目):B2B 产品的后台管理系统,主要是公司内部流程、审批等内容管理。

因为管理产品与应用产品所用开源框架一致,为了便于项目整体维护,同步开源框架的版本,所以将管理产品代码迁移到应用产品项目中。

两者合并后,所涉及页面巨多,而且随着时间推移,增加的页面也越来越多,导致项目打包时间从刚开始的几分钟,直接飙升到将近10分钟。如果 jenkins 部署时,依赖安装的网络再不给力,部署时间就更辣眼睛了。

优化方案

1. 优化项目构建打包路径

Vite 使用 Rollup 来打包代码,是可以预配置的,可输出用于生产环境的高度优化过的静态资源。

Rollup 配置文档中第一项就是 external,这个配置可以指定那些模块(文件夹)不参与打包。

因为应用产品与管理产品是不同的项目,所以当应用产品打包的时候,就可以将管理产品的代码排除在外,不打包进入 bundle 中。反之亦然。

仅通过这一项优化,CRM 系统的构建时间由 470s 降为 200s。CMS 系统构建时间 由 430s 降为 160s。优化后节省的时间还是蛮多的。

上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import type { RollupOptions } from 'rollup';
import fsExtra from 'fs-extra';
import path from 'path';

export const createRollupOptions: (
platform: ViteEnv['VITE_GLOB_YT_PLATFORM'],
) => RollupOptions = (platform) => {
const external: RegExp[] = [];

let externalRegs: RegExp[] = [];

if (platform === 'CMS') {
// 应用产品 ------- 移除 Demo、CRM相关代码
externalRegs = [/\/src\/views\/demo\/.*/, /\/src\/views\/crm\/.*/, /\/src\/views\/scm\/.*/];
} else if (platform === 'CRM') {
// 管理产品 ------- 移除 CMS 相关代码
let folderNames = fsExtra.readdirSync(path.join(process.cwd(), '/src/views/'))
folderNames = folderNames.filter(name => !['crm','scm', 'sys', 'dashboard'].includes(name))

externalRegs = folderNames.map(name => new RegExp(`/src/views/${name}`))
}

externalRegs.forEach((reg) => {
external.push(reg);
});

console.log('rollupOptions', externalRegs);
return {
external,
};
};

2. rollup-plugin-visualizer

rollup-plugin-visualizer 是 Rollup 中打包体积可视化插件(对应 webpack中的 webpack-bundle-analyzer),在打包的时候,使用该插件,会在项目根目录下生成一个 stats.html 文件, 在浏览器中打开,是可视化的打包后的体积信息。

1
yarn add rollup-plugin-visualizer -D
1
2
3
4
5
6
7
8
9
10
11
import { createVisualizer } from 'rollup-plugin-visualizer';

// 略略略
plugins: [
createVisualizer({
open: true,
gzipSize: true,
brotliSize: true,
}),
]
// 略略略

image-20240722163210198

image-20240722163319153
image-20240722164052829

这里边可以很明显的看到,tinymce 这个依赖库,大小竟有 3.2MB,占整个打包文件的 19%。整个项目的打包时间也是达到了269秒

通过检索整个项目,发现这个依赖只有 4 处使用,并且其中 1 处还是 demo 中的代码。

emmm,先把这个依赖移除,看下可以节省多少时间。

image-20240722165823305

移除之后,打包时间来到了207秒,减少了足足 60秒

现在我们也开发了一款 editor 编辑器,如果有时间,可以将 tinymce 替换掉。但是要花费时间去兼容一些历史数据,还是有一些代价的。

当然,其他的插件也可以如法炮制,找到那些占用空间大的内容,逐个排查优化,还是可以缩短不少时间的。

CDN加速

像图片、静态js、svg等,都可以放到 oss 中,使用 CDN 地址进行加速,可以避免进入打包构建内容中,一定程度上也可以减少打包时间(蚊子腿也是肉,积少成多^_^)。

生产环境关闭 sourceMap

sourceMap 本质上是一种映射关系,打包出来的 js 文件中的代码可以映射到代码文件的具体位置,这种映射关系会帮助我们直接找到在源代码中的错误。打包速度减慢,生产文件变大,所以开发环境使用 sourceMap,生产环境则关闭。