从体积焦虑到按需加载
从体积焦虑到按需加载
写了个中文字体子集化工具 charbi-font
开发契机
受公司大佬做的工具的启发,了解到字体子集化这条路径。说来惭愧,入行前端这么多年了,还是头一次知道
字体子集化确实能显著减小体积,但落地到工作中的项目时,发现还有一些绕不开的需求
发现需求
多字重支持
阿里巴巴普惠体在项目里用到 5 种字重,希望能自动合并管理,不想手动维护多份配置
文本内容变化
新项目迭代快,要考虑文案、字重可能会有变更,以及后续随着迭代的文案变更等,我太懒,不想每次都手动维护字符清单
上传分发能力
Base64 自带 33% 体积增加,受小程序包体限制影响,感觉早晚需要放到云存储,所以需要有上传、构造版本路径等能力
charbi-font 做了什么
charbi-font 覆盖了从扫描、构建到分发的完整链路:
- 递归扫描源码,提取真实使用字符
- 扫描时自动过滤注释内容
- 原字体本地缓存,避免反复下载造成的浪费
- 上传 CDN(如 COS),支持并发上传和远端存在判断
- 支持
extraText手动补充动态文本 - 输出
woff / woff2 / ttf - 自动生成 CSS/SCSS 样式文件
- 支持多字重合并管理
实测压缩效果
| 名称 | 原体积(MB) | 压缩体积(KB) | 压缩率 |
|---|---|---|---|
| Alibaba PuHuiTi (5 weights) | 35 MB | 985 KB | 97.22% |
| DingTalkJinBuTi | 2 MB | 214 KB | 89.71% |
| DelaGothicOne | 2 MB | 144 KB | 94.08% |
| Total | 39 MB | 1,343 KB | 96.63% |
其他特性
Vite 插件支持
通过 Vite 插件,实现业务侧更多能力
配置 Vite 插件...查看更多
1
2
3
4
5
6
7import CharbiFont from 'charbi-font/vite'
export default defineConfig(() => {
plugins: [
CharbiFont()
]
})使用 TS 可以在
tsconfig.json中添加类型支持1
2
3
4
5{
"compilerOptions": {
"types": ["charbi-font/client"]
}
}获取加载字体所需字段
因为需要基于版本号创建不同的目录,防止多版本相互影响。在生成的样式中是自动写入的,但有时也会使用
uni.loadFontFace在 JS 中加载字体业务侧无需再手写一份字重与文件名对照表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import { BUILD_FONT_FACES, FONT_ASSET_BASE_URL, FONT_BUILD_VERSION } from 'virtual:charbi-font'
for (const face of BUILD_FONT_FACES) {
const base = FONT_ASSET_BASE_URL
if (!base)
continue
uni.loadFontFace({
global: true,
family: face.family,
source: `url("${base}/${face.file}")`,
desc: {
style: face.style,
weight: face.weight,
variant: face.variant
}
})
}业务侧无需再手写一份...查看更多
使用
安装
1 | pnpm add charbi-font -D |
配置
目录下创建 fonts.config.ts,配置示例
1 | import { defineConfig } from 'charbi-font/config' |
命令
1 | # 构建及上传 |
关于名称
最开始让 AI 起名,我说可以造组合字,于是在一堆名称中我一眼看到了 char + build = charbi(你没有偷摸骂我吧?)
开源
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 怠惰のコエ - imba久期 BLOG!
评论
