Blog/source/_posts/2021/03/中文网页字体动态裁剪.md
2022-03-16 22:24:24 +08:00

99 lines
3.8 KiB
Markdown

---
author: SouthFox
title: 中文网页字体动态裁剪
date: 2021-03-12 21:28:56
tags:
- 技术
- 字体
category: 技术
toc: true
---
首先,我先在放个【矣】在这里。
<!--more-->
比起字母系统语言,汉语在计算机世界上有着天然的弱势,**锟斤拷**和**锘锘锘**这些编码问题本身就令人头大了,尤其对于互联网这个寸土寸金之地,想要在网页内展现自定义字体,首先就要先加载个几兆大小的字体文件,要这么做那就是极度的浪费和折磨了。
所以字体裁剪是必要的,有两种方向:
- 提前准备常用字集进行裁剪
- 提前计算出需要展示的字集再进行裁剪
第一种方式就是突出一个极致的懒,只需要做一次,就能不用再管了。缺点就是总会有不在常用字体里的“常用字”,这样网页加载出来的效果就会形成“犬牙交错”之感,看起来非常辣眼(要是选用的字体和默认字体差别非常大的话)。而且常用字内其实也不是每个字都用上了,所以还是会有浪费。
第二种方式就更优雅一点了,能保证字体里的每个字都是用上的。缺点就是麻烦了点儿,不过只要写个自动化脚本,这点麻烦也不算麻烦了。
## 压缩方案
当选 [fonttools](https://github.com/fonttools/fonttools) ,至少这项目现在还活跃着,其他类似的字体项目都停滞了蛮久时间的了……好像。
要使用直接通过 ```pip install``` 安装 ```fonttools```就行了,要是还想压成 ```woff2``` 这种压缩率更高的格式还得再安装个 ```brotli``` 。
使用命令:
```pyftsubset <字体>.ttf --text-file=<字符集文件>```
当然,也可用 ```--text=``` 的选项来直接后面跟所需字符。
要压成 ```woff2``` 格式可以用 ```fonttools ttLib.woff2 compress <压缩后字体>.woff2 <被压字体>.ttf``` 的方式。
### 脚本代码
反正一个简单粗暴的循环怼上去就得了,去重可以用集合来去。
```python
import os
path = os.getcwd()
filelist = []
for root, dirs, files in os.walk(path + '/source'):
for name in files :
filelist.append(os.path.join(root, name))
strset = set([])
for filename in filelist:
if '.md' not in filename:
continue
with open(filename, "r",encoding='utf-8') as f:
for subset in f.read():
strset.add(subset)
str_ = ''
a = 0
with open('strdb.txt', "w") as f:
for i in list(strset):
str_ += i
a += 1
print('%d Characters in all files.'%a)
print(str_)
f.write(str_)
```
将 ```source``` 下的 ```md``` 文件的字符提出来,再写入到 ```strdb.txt``` 以带后续使用。当然直接用 ```--text=``` 选项直接塞进命令里也可以,反正我是喜欢先写进文件的。
最后生成的字体文件在 80kb 左右,对于网页来说,已经是可以接受的程度了,当然这跟我选择的字体有关,是一款像素字体,不怎么占空间,如果是常规字体的话,大概会在上两三百左右吧。
## 坑
1. 首先是 ```Travis``` 部署上得用 ```python3``` 环境,要特别声明一下,二环境下会输出个零蛋,应该是版本之间语法的锅?
2. 代码里没有解析配置文件里的中文语句,所以标语口号这种,可能就会没被解析到,不过我懒地再一个一个引入配置文件,所以还不如……~~我先在放个【矣】在这里。~~
3. 确保文本在网页字体加载期间保持可见状态,即设置 `font-display: swap` 选项 在`@font-face` 内,要不然的话字体没加载出来文本会消失掉。
## 参考
1. [Fonttools](https://github.com/fonttools/fonttools)
2. [中文字体压缩的那些事——涂雨期的博客](https://hsingko.github.io/post/compress_webfont/)
3. [Font display](https://web.dev/font-display/)