APP字体库文件处理方案
一、前言
有时候需要让页面加载自定义字体文件,但是通常的字体格式(TTF
、OTF
)体积太大了,这就需要将其转换为更小体积的字体文件格式(WOFF2
)。
之前尝试使用类似 convertio 在线工具去转换 OTF 字体文件,但是不知道为何转换出来的字体损坏了,无法使用。经过多方面研究,现在找到了一种本地压缩字体可行的方法,因此分享给大家。
二、字体格式科普
常见的字体格式有以下几种,这里只作简单介绍。
2.1 TTF
TTF(TrueTypeFont
)是 Apple 公司和 Microsoft公司 共同推出的字体文件格式,随着 windows 的流行,已经变成最常用的一种字体文件表示方式。
这种格式的字体文件体积比较大,以思源宋体为例,字体文件可以达到 24MB+,通常只用作安装到计算机中的字体,或者在网页中设备不支持 WOFF2
字体情况的兜底处理。
2.2 OTF
OpenType
,是一种可缩放字体(scalable font
)电脑字体类型,采用PostScript
格式,是美国 Microsoft公司 与 Adobe公司 联合开发,用来替代TrueType
字体的新字体。这类字体的文件扩展名有.otf、.ttf、.ttc
,类型代码是OTTO
,现行标准为OpenType 1.9
。
可以理解为和 TTF
字体差不多,这里我们主要讨论体积问题,OTF
字体文件体积也很大,基本和 TTF
差不多。
2.3 WOFF & WOFF2
Web开放字体格式(Web Open Font Format
,简称WOFF
)是一种网页所采用的字体格式标准。此字体格式发展于2009年,由万维网联盟的Web字体工作小组标准化,现在已经是推荐标准。此字体格式不但能够有效利用压缩来减少文件大小,并且不包含加密也不受DRM
(数字著作权管理)限制。
这是专门给网页使用的字体格式,体积非常小,实测压缩思源宋体字体文件,可以把体积压缩到 OTF
字体 70% 的大小。
WOFF
和 WOFF2
的区别在于:WOFF
本质上是包含了基于SFNT
的字体(如TrueType
、OpenType
或其他开放字体格式),且这些字体均经过WOFF
的编码工具压缩,以便嵌入网页中。WOFF 1.0使用zlib压缩,文件大小一般比TTF小40%。而WOFF 2.0
使用Brotli
压缩,文件大小比上一版小30%。
因此,一般推荐直接使用 WOFF2
。
2.4 SVG
可缩放矢量图形(英语:Scalable Vector Graphics
,缩写:SVG)是一种基于可扩展标记语言(XML),用于描述二维矢量图形的图形格式。SVG由W3C制定,是一个开放标准。
这种字体是非常早期的标准,已经不推荐使用。我们可以从 caniuse (针对前端开发人员定制的一个查询CSS、Js在流行浏览器钟的特性和兼容性的网站,可以很好的保证网页的浏览器兼容性。) 里面查到它的兼容性非常差:
三、字体库压缩
这部分是正式的压缩方法了,主要分为两步,分别是:取子集、压缩。
这里使用到的是 Python
的一个库:fonttools
,使用最新版 Python
的 pip 命令安装即可在 Shell 中使用:
pip install fonttools
3.1 取子集
3.1.1 fonttools
中文汉字数量很多,以思源宋体为例,思源宋体遵循 GB18030
和通用规范汉字表,包含 8105 个规范字(来源:少数派),可能还有其他语言的字符,实际字符数量肯定是远超这个数字的。
实际上,常用汉字数量也就 3500 个左右,如果你的文本相对固定,可以考虑删减掉其他不常用的汉字。
极端做法是只保留文本中出现的字符,其他的全部删掉,但是我个人更倾向于折中保留 5000 汉字,在未来如果修改了文本,也不至于每次都要重新压缩一遍字体。
这种删减字符的做法叫“取子集”。取子集我们需要定义一个纯文本文件,里面包含所有要保留的字符,这里给大家分享一个自己正在使用的文件:现代汉语常用 5000 字.txt。
参数详情可执行 pyftsubset --help
命令查看。
使用以下命令即可对字体文件取子集:
fonttools subset "$input_file" --text-file="$text_file" --output-file="$output_file"
注⚠️:
--text-file=<PATH>
中的PATH为汉字文本;--unicodes-file=<PATH>
中的PATH为unicode
或16进制格式的汉字文本;
变量含义:
$input_file
:输入的字体文件。$text_file
:定义保留字符的纯文本文件路径。$output_file
:输出的字体文件路径。
经过测试对思源宋体取完子集后,文件体积从 25.4MB 减少到了 2.5MB,足足小了 1/10。
3.1.2 Fontmin
Fontmin 是一个纯 JS 字体子集化方案。利用 Fontmin 可以提取 TTF
字体文件中需要用到的字符,然后转换为 TTF
文件输出,从而实现“压缩”的效果。
类似更多的字体处理工具包括在线字体压缩 transfonter.org、font-spider
注⚠️:
- 使用 Fontmin、font-spider压缩的字体包必须为
ttf
类型。
3.1.3 字体筛选优缺点
优点:字体包体积被优化,加载性能提升;
缺点:以上字体筛选工具虽然好用,但是由于其原理是直接分析本地静态 CSS
与 HTML
文件获取使用过的字符,这样一来,对于动态生成的文字,就没有办法使用静态字体筛选方案了。尤其在当下,很多框架都是数据驱动的,很多文字都不会直接出现页面文件中。
3.2 压缩
取完子集后,我们将对字体文件进行压缩,主要是压缩成 WOFF2
格式。
压缩命令很简单:
fonttools ttLib.woff2 compress "$input_file" -o "$output_file"
变量含义:
$input_file
:输入的字体文件。$output_file
:输出的字体文件路径。
对上面已取子集的字体经过压缩后,体积差不多减少了 70%,从 2.5MB 减小到了 1.9MB。
关于fontTools
的参数,可通过 fontTools --help
查看。
3.3 组合方法
经过上面两个步骤后,字体体积大约减少了 1/10 还要小,极大提高了加载速度。
但是有时候需要用到一些非常用但是又不是很生僻的汉字,这里分两种情况:如果文本是确定的,可以将这些字加入到定义保留字符的文件中即可;如果文本不确定(比如有用户输入),又对字体要求较高,也可以仅仅执行压缩步骤,也能将字体体积减小到 70%,总比没有好。
四、拓展阅读
- 点赞
- 收藏
- 关注作者
评论(0)