建站时很多博主希望用个性化字体,能很好地美化博客界面,但是使用之后才发现,字体的体积巨大,尤其是中文字体,动不动就可能有几十 MB,在这巨大体积的压迫之下不得不选择放弃使用。但是怎么能放弃呢!!!这里就教给大家一种简单精简字体的方式——通过 fontTools。

1 安装 fontTools

fontTools 是一个 Python 库,想要使用需要先下载 Python,之后通过 pip 安装:

1
$ pip install fontTools

2 基本使用

我们需要使用的是其中的 pyftsubset 命令,在命令行下的基本操作为:

1
$ pyftsubset {源字体文件位置} --text={需要的字符} --output-file={输出字体文件位置}

只要给出网站所需要的字符,就能轻松生成精简后的字体,可以超大幅度地减小字体体积。

以思源宋体 (Source Han Serif SC) 为例,输入:

1
$ pyftsubset "SourceHanSerifSC-Regular.otf" --text="幸运小站" --output-file="SourceHanSerifSC-Regular.ttf"

这里只保留了幸运小站四个字符,我们看看精简前后字体文件大小的对比图:

字体文件由 30826 KB 直接降到 4 KB,降幅达到 99.99%!将其上传至 FontDrop!,结果如下图所示:

可见压缩后的字体文件确实只包含这四个字符。重复出现是因为思源宋体中多种语言共用了同一个 Unicode,具体原因可以参考 → 知乎回答:思源黑体 (Source Han Sans) 的各个版本有什么不同?

3 网站使用

知道了基本的使用方式,接下来我们就将字体用到网站建设中来。

3.1 获取文字

文字分布在各个网页源码中,我们要想办法遍历所有网页源码并提取出所有的文字,这里给出一个 Python 写的模板供大家使用,先安装依赖:

1
$ pip install bs4 lxml requests

然后复制以下代码并根据实际情况修改:

 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
import os
from bs4 import BeautifulSoup as bs

exclude_file_list = []  # 所有需要被排除的文件列表
exclude_dir_list = []  # 所有需要被排除的文件夹列表

root = "."  # 根目录
result_path = "all_content.txt"  # 所有文字的存放路径


def get_text(file_path):
    soup = bs(open(file_path), 'lxml')
    content = set(soup.text)
    return content


g = os.walk(root)
all_content = set()

for path, dir_list, file_list in g:
    for exclude_dir in exclude_dir_list:
        if exclude_dir in path:
            break
    else:
        for file_name in file_list:
            if file_name in exclude_file_list:
                continue
            file_path = os.path.join(path, file_name)
            if os.path.splitext(file_path)[1] == '.html':
                content = get_text(file_path)
                all_content |= content

with open(result_path, "w", newline="\n") as f:
    f.write(''.join(sorted(all_content)))

运行出来的结果就是一个包含所有源码中出现字符的文件,接下来就可以由此精简字体了。

3.2 精简字体

这时候我们可以直接打开生成的文件,复制全部字符,然后按照第 2 节的方式生成就可以了:

1
$ pyftsubset {源字体文件位置} --text={需要的字符} --output-file={输出字体文件位置}

或者选择直接让 pyftsubset 从文件中读取:

1
$ pyftsubset {源字体文件位置} --text-file={生成文件位置} --output-file={输出字体文件位置}

3.3 注意事项

每次新增文章的时候,可能会添加新的字形,因此务必在发表新文章之前重新生成一次字体文件,以确保所有的文字都能被字体文件覆盖到。

当然,fontTools 的功能非常强大,感兴趣的读者可以通过官方文档来进一步学习,这里就不逐一展开说明了。