Vite Packaging Optimization 可通过压缩文件、图像和字体来优化大小
分析可优化项目
先通过'rollup-plugin-visualizer' 来分析打包的结果
npm i rollup-plugin-visualizer -D
plugins: [
visualizer({open: true}),
react(),
],
看体积占用图,对于是否进行分区打包没有影响,不写下面的就都会打包到assets一个文件夹里面
build: {
rollupOptions: {
output: {
chunkFileNames: "js/[name]-[hash].js", // 生成chunk文件名的名称
entryFileNames: "js/[name]-[hash].js", // 包的入口文件名称
assetFileNames: "[ext]/[name]-[hash].[ext]", // 资源文件像 字体,图片等
},
},
},
此时打包如下,这里也会提示gzip的压缩预期
gzip,Brotli文件压缩
文件压缩会压缩js,css,html,svg文件。字体,图片文件等不会压缩
通过vite-plugin-compression来压缩
npm install vite-plugin-compression -D
- gzip是在deflate上的算法,deflate就是打包成zip的算法
ViteCompressionPlugin({
algorithm: "gzip",
ext: ".gz",
deleteOriginFile: true,
}),
- Brotli 是谷歌的算法,压缩率好于gzip,但是只支持HTTPS
ViteCompressionPlugin({
algorithm: "brotliCompress",
ext: ".br",
deleteOriginFile: true,
}),
gzip压缩后空间极大减少占用,此示例中8.67->2.75MB
Brotli 会有更大的压缩率,此例子中8.67->2.46MB
图片压缩
图片压缩使用vite-plugin-imagemin
npm i vite-plugin-imagemin -D
根据你需要的压缩配置即可
viteImagemin({
gifsicle: {
optimizationLevel: 7,
interlaced: false,
},
optipng: {
optimizationLevel: 7,
},
mozjpeg: {
quality: 20,
},
pngquant: {
quality: [0.8, 0.9],
speed: 4,
},
svgo: {
plugins: [
{
name: "removeViewBox",
},
{
name: "removeEmptyAttrs",
active: false,
},
],
},
}),
压缩结果如下,本来图片就够小的情况下压缩率不高
字体压缩
现在大部分内容都已经压缩,只剩下字体文件仍然比较大
通过fontmin来进行压缩,取出使用的子集而不是全用
npm install --save-dev fontmin
则就需要扫描用到的字符,在根目录下写一个node环境的扫描函数即可
扫描渲染视图views文件夹下的所有文件,取出里面用到的字符,加入Set中去重,之后将其转换为fontmin所需的使用字符连成的字符串即可
const fs = require("fs");
const Fontmin = require("fontmin"); // 需要借助 fontmin 插件
// 获取指定目录下的所有文件
function getFiles(dir) {
const results = [];
const list = fs.readdirSync(dir);
for (const file of list) {
const filePath = `${dir}/${file}`;
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
results.push(...getFiles(filePath));
} else {
results.push(filePath);
}
}
return results;
}
// 扫描目录并获取所有字符
function scanDirectory(dir) {
let set = new Set();
const files = getFiles(dir);
for (const file of files) {
const content = fs.readFileSync(file, "utf8");
const currentSet = new Set(content);
set = new Set([...set, ...currentSet]);
}
return set;
}
// 生成最终的 HTML 代码
function generateFinalHTML(finalString) {
const fontmin = new Fontmin()
.src("./src/assets/fonts/YouSheBiaoTiHei.ttf") // 源字体文件路径
.dest("./src/assets/fonts/fontmin/") // 压缩后文件存放路径,最终使用的是这个压缩后的文件
.use(
Fontmin.glyph({
text: finalString, // 也可以直接指定需要生成的字符集
hinting: false,
})
);
fontmin.run((err) => {
if (err) {
throw err;
}
});
}
// 扫描指定目录并生成最终的 HTML 代码
let set = scanDirectory("src/views");
let finalString = Array.from(set).join("");
generateFinalHTML(finalString);
console.log("共生成:" + finalString.length + "个字符");
当然这是有缺陷的,只会保存本地项目里使用的静态字符,对于后端返回的没在本地出现的字符是没覆盖到的,是不完全的子集,可以考虑使用额外的常用内容添加到字符串中进行拓展实现覆盖
Vite压缩效果
现在我们已经把dist文件夹从最初的8.67MB,压缩到了很小的1.50MB