Files
novalon-website/scripts/optimize-font.py
T
张翔 2c01752017 perf(fonts): 优化字体加载性能并添加子集化脚本
将 TTF 字体转换为更高效的 WOFF2 格式,添加字体子集化脚本以减小文件大小
优化字体预加载和显示策略,改进无障碍标签
2026-04-12 13:52:54 +08:00

135 lines
3.6 KiB
Python

#!/usr/bin/env python3
"""
字体子集化脚本 - 优化 AoyagiReisho 字体
只保留网站实际使用的汉字字符,大幅减小字体文件大小
"""
import os
import sys
from pathlib import Path
try:
from fontTools.ttLib import TTFont
from fontTools.subset import Subsetter, Options
except ImportError:
print("❌ 缺少 fonttools 库")
print("请运行: pip install fonttools brotli")
sys.exit(1)
def create_font_subset(
input_font: str,
output_font: str,
chars_file: str,
output_format: str = "woff2"
):
"""
创建字体子集
Args:
input_font: 输入字体文件路径
output_font: 输出字体文件路径
chars_file: 包含所需字符的文本文件
output_format: 输出格式 (ttf, woff, woff2)
"""
print(f"📝 正在读取字符列表: {chars_file}")
# 读取所需字符
with open(chars_file, 'r', encoding='utf-8') as f:
chars = set(f.read())
# 移除空白字符
chars = chars - {'\n', '\r', '\t', ' '}
print(f"✅ 共需保留 {len(chars)} 个字符")
# 加载字体
print(f"📥 正在加载字体: {input_font}")
font = TTFont(input_font)
original_size = os.path.getsize(input_font) / 1024 / 1024
print(f"📊 原始字体大小: {original_size:.2f} MB")
# 创建子集化器
options = Options()
# 不删除必要的表
options.flavor = output_format
subsetter = Subsetter(options=options)
# 添加所需字符
subsetter.populate(chars)
# 执行子集化
print("⚙️ 正在创建字体子集...")
subsetter.subset(font)
# 保存字体
print(f"💾 正在保存字体: {output_font}")
font.save(output_font)
font.close()
# 统计结果
new_size = os.path.getsize(output_font) / 1024 / 1024
reduction = (1 - new_size / original_size) * 100
print(f"\n✨ 优化完成!")
print(f"📊 新字体大小: {new_size:.2f} MB")
print(f"📉 减小比例: {reduction:.1f}%")
print(f"💾 节省空间: {(original_size - new_size):.2f} MB")
def main():
# 项目根目录
project_root = Path(__file__).parent.parent
# 输入输出路径
input_font = project_root / "public/fonts/AoyagiReisho.ttf"
output_dir = project_root / "public/fonts"
chars_file = project_root / "scripts/font-chars.txt"
# 检查文件是否存在
if not input_font.exists():
print(f"❌ 字体文件不存在: {input_font}")
sys.exit(1)
if not chars_file.exists():
print(f"❌ 字符文件不存在: {chars_file}")
sys.exit(1)
# 创建输出目录
output_dir.mkdir(parents=True, exist_ok=True)
# 创建 WOFF2 格式
output_woff2 = output_dir / "AoyagiReisho.woff2"
print("\n🎨 创建 WOFF2 格式字体 (推荐)")
create_font_subset(
str(input_font),
str(output_woff2),
str(chars_file),
output_format="woff2"
)
# 创建 TTF 格式 (作为备选)
output_ttf = output_dir / "AoyagiReisho-subset.ttf"
print("\n🎨 创建 TTF 格式字体 (备选)")
create_font_subset(
str(input_font),
str(output_ttf),
str(chars_file),
output_format=None
)
print("\n" + "="*60)
print("✅ 所有字体优化完成!")
print("="*60)
print(f"\n📁 输出文件:")
print(f" - WOFF2: {output_woff2}")
print(f" - TTF: {output_ttf}")
print(f"\n💡 建议: 在 CSS 中优先使用 WOFF2 格式")
print(f" font-display: swap 可确保字体加载时文字可见")
if __name__ == "__main__":
main()