Vite打包优化,通过文件,图片,字体压缩优化大小

分析可优化项目

先通过'rollup-plugin-visualizer' 来分析打包的结果

npm i rollup-plugin-visualizer -D

javascript 复制代码
plugins: [
    visualizer({open: true}),
		react(),
	],

看体积占用图,对于是否进行分区打包没有影响,不写下面的就都会打包到assets一个文件夹里面

javascript 复制代码
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的算法
javascript 复制代码
ViteCompressionPlugin({
			algorithm: "gzip",
			ext: ".gz",
			deleteOriginFile: true,
		}),
  • Brotli 是谷歌的算法,压缩率好于gzip,但是只支持HTTPS
javascript 复制代码
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

根据你需要的压缩配置即可

javascript 复制代码
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所需的使用字符连成的字符串即可

javascript 复制代码
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

相关推荐
小村儿1 天前
给 AI Agent 装上"长期记忆":Karpathy 的 LLM Wiki 思想,我做成了工具
前端·后端·ai编程
竹林8181 天前
用ethers.js连接MetaMask实现Web3钱包登录:从踩坑到稳定运行的完整记录
前端·javascript
heyCHEEMS1 天前
如何用 Recast 实现静态配置文件源码级读写
前端·node.js
心连欣1 天前
从零开始,学习所有指令!
前端·javascript·vue.js
review445431 天前
大模型和function calling分别是如何工作的
前端
东东同学1 天前
耗时一个月,我把 Nuxt 首屏性能排障经验做成了一个 AI Skill
前端·agent
冴羽1 天前
超越 Vibe Coding —— AI 辅助编程指南
前端·ai编程·vibecoding
梦想的颜色1 天前
一天一个SKILL——前端最佳自动化测试 webapp-testing
前端·web app
SoaringHeart1 天前
Flutter进阶:放弃 MediaQuery.of(context) 使用 NScreenManager
前端·flutter
openKaka_1 天前
从 scheduleUpdateOnFiber 到 Root 微任务调度:React 如何把更新交给调度系统
开发语言·前端·javascript