前言
最近看到越来越多的网站使用字体分段加载(貌似都白嫖的B站)
不过博主找了半天,也是没有找到字体切片的相关文章
所以就手搓了一个…
博主也去了解了下字体切片原理,看起来就是把一个字体内的文字打散,分成很多个文件,浏览器需要的时候加载对应文件
(谷歌字体有篇文章: 貌似写着这样可以减少大约30%的加载大小)
tips: 手搓完成后,我受到了巨大的打击,因为别人告诉我Github上有(不过我去看了下,貌似不全)
开始
准备材料: 一台PC
, Python 3.7
及以上环境(博主是Python 3.9
)
如果没有环境或者遇到问题(或者不会)可以在侧边栏公告那里加入博客群聊,寻求帮助
安装依赖
1
| pip install fonttools Brotli
|
准备运行时环境
然后新建一个文件夹(程序运行时会生成缓存文件)
比如 font
然后把要转换的 TTF
格式字体复制粘贴进去
新建一个 .py
文件,把以下代码丢进去
main.py1 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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| import os, json from fontTools.ttLib import TTFont
字体文件名称 = "HarmonyOS_Sans_SC_Regular.ttf" 保存的字体文件名称 = "HarmonyOS_Sans_SC_Regular_" 字体切片字数 = 2500 css_font_family = "HarmonyOS Sans SC Regular" css_font_family_first = 'local("HarmonyOS Sans SC Regular"), local("HarmonyOS Sans SC"), '
print("正在加载字体文件......")
with TTFont(字体文件名称 ) as font: font_data = font.getGlyphOrder() print("加载字体文件成功")
with open("data.json", "w", encoding="utf-8") as f: writer_json = json.dumps(font_data, ensure_ascii=False, indent=2) f.write(writer_json)
print("正在生成数据......")
font_unicodes = []
for i in font_data: if i.startswith("uni"): font_unicodes.append(i)
with open("data1.json", "w", encoding="utf-8") as f: writer_json = json.dumps(font_unicodes, ensure_ascii=False, indent=2) f.write(writer_json) writer_json = []
font_unicodes = [font_unicodes[i:i + 字体切片字数] for i in range(0, len(font_unicodes), 字体切片字数)]
with open("data2.json", "w", encoding="utf-8") as f: writer_json = json.dumps(font_unicodes, ensure_ascii=False, indent=2) f.write(writer_json) writer_json = []
unicodes = [] for i in font_unicodes: start_key = i[0].replace("uni", "") end_key = i[-1].replace("uni", "") unicodes.append(f"U+{start_key}-{end_key}")
with open("data3.json", "w", encoding="utf-8") as f: writer_json = json.dumps(unicodes, ensure_ascii=False, indent=2) f.write(writer_json) writer_json = []
print("数据生成成功,开始转换!")
列表长度 = len(unicodes)
print(f"列表长度: {列表长度}")
raw_css = ""
for i in range(列表长度): 当前字符集 = unicodes[i] print(f"正在处理字符集 {当前字符集}")
字体保存目录 = f"./fonts/{保存的字体文件名称}{i}.woff2" 命令 = f'pyftsubset {字体文件名称} --unicodes="{当前字符集}" --output-file="{字体保存目录}" --flavor="woff2' print(f"执行命令: {命令}") os.system(命令)
raw_css = raw_css + f''' @font-face {{ font-family: "{css_font_family}"; font-style: normal; /* font-weight: 400; */ font-display: swap; src: {css_font_family_first}url("{字体保存目录}") format("woff2"); unicode-range: {当前字符集} }} '''
raw_css = raw_css + f''' body {{ /* 设置字体 */ font-family: "{css_font_family}", sans-serif !important; }} '''
with open("font.css", "w", encoding="utf-8") as f: f.write(raw_css)
|
然后在文件开头修改配置,配置干嘛的都注释好了
看到这里想必各位是不是马上准备双击运行了,
但我想说一句还要在文件夹内新建个 fonts
文件夹,存放生成的字体文件。
然后就可以愉快的双击运行了,
(tips: 建议运行时看着,因为程序逻辑问题有时候报错不会退出)
结束后你就会在这个文件夹内找到个 font.css
和有一堆字体切片文件的 fonts
文件夹
这些东西想必大家都知道是干嘛用的
把 font.css
和 font
文件夹 放在你的cdn里的同一个目录里,
然后主题引入下css
就可以开始游玩了
tips:
字体css建议使用用异步加载
1
| <link rel="stylesheet" href="你的cssURL" media="defer" onload="this.media='all'">
|