字体压缩终极解决方案

guide
2 min
字体压缩终极解决方案

Fontmin提供了一种简单可行的字体压缩思路:先找到所有的文字,再使用fonttools工具将原始字体压缩成字符子集

壹丨问题分析

前面几种字体压缩方法并不能满足要求

使用CloudConvert无法压缩NotoSerifSC.otf字体

使用fonttools压缩后的字体仍然比较大,网页加载慢

使用Fontmin没法为整个博客压缩对应的字体

但是,fonttoolsFontmin提供了一种简单可行的思路:

  1. 先找到网站涉及的所有文字
  2. 构成fonttools所使用的sc_unicode.txt
  3. 使用fonttools工具压缩字体

贰丨代码实现

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
32
33
34
35
36
37
import os

SITE_PATH = '../site'
AIM_FONT = 'NotoSerifSC.otf'
FONTS_PATH = './Fonts'


def get_letters():
char_list = []
for root, dirs, files in os.walk(SITE_PATH):
for file in files:
if file.endswith('.html'):
html_path = os.path.join(root, file)
with open(html_path, 'r', encoding='utf8') as f:
contents = f.readlines()
for content in contents:
char_list.extend(list(content))
char_simple_list = list(set(char_list))
return char_simple_list


def generate_fonts(letter_list):
char_unicode = [str(item.encode('unicode_escape').decode()).split('u')[-1].upper() + '\n' for item in
letter_list if '\u4e00' <= item <= '\u9fff']
with open(f'{FONTS_PATH}/sc_unicode.txt', 'w', encoding='utf8') as f:
f.writelines(char_unicode)

# pip install fonttools
cmd = f'cd {os.path.abspath(FONTS_PATH)} && pyftsubset {AIM_FONT} --unicodes-file=sc_unicode.txt'
re = os.system(cmd)
assert [1, 0][re], '生成字体失败'


if __name__ == '__main__':
letters = get_letters()
generate_fonts(letters)

运行后,会在字体文件夹生成新的字体xxx.subset.otf

1
2
3
4
5
6
.
├── Fonts
│ ├── NotoSerifSC.otf
│ ├── NotoSerifSC.subset.otf
│ └── sc_unicode.txt
└── generate_fonts.py

叁丨结果分析

gallery.mastermao.cn网站为例,提取的sc_unicode.txt文件内含740个汉字的Unicode码,压缩后的字体体积对比:

NotoSerifSC.otfNotoSerifSC.subset.otf压缩比
10952KB234KB2.14%

撒花~ ✿✿ヽ(°▽°)ノ✿