Files
blog/themes/Ying/FONT_OPTIMIZATION_FALLBACK.md
T

7.4 KiB
Raw Blame History

🔤 字体优化 - 替代方案(Unicode范围限制)

由于glyphhanger扫描了太多字符导致失败,这里提供两个替代方案:


方案A:Python脚本(推荐)✅

这个脚本更智能,只提取实际使用的字符。

步骤1:确保已构建Hugo

cd E:\GitHub\blog
hugo --destination=public

步骤2:安装Python依赖

pip install fonttools brotli

步骤3:运行Python脚本

python scripts/subset-font-safe.py

预期输出:

🔤 字体子集化工具(安全版本)
==================================================
🔍 扫描目录: content, layouts, public
📝 提取了 1,234 个唯一字符
📊 原始字体信息:
   字符数: 20,000
   文件大小: 1200.0 KB
✂️  正在生成子集字体...
✅ 子集化完成!
📊 优化结果:
   子集字符数: 1,234
   子集文件大小: 150.0 KB
   减少: 1050.0 KB (87.5%)

步骤4:验证生成的文件

ls -lh themes/Ying/static/font/zql-v2-subset.*

预期大小:

  • zql-v2-subset.woff2: 100-200KB
  • zql-v2-subset.woff: 150-300KB

方案B:手动Unicode范围(最简单)

如果Python方案太复杂,可以直接修改CSS,使用更小的Unicode范围。

原理

中文字符的Unicode范围:

  • CJK统一汉字: U+4E00 - U+9FFF(常用汉字,约20,000个)
  • CJK扩展A: U+3400 - U+4DBF(生僻字)
  • CJK扩展B: U+20000 - U+2A6DF(更生僻的字)

大多数博客只需要 CJK基本区(U+4E00 - U+9FFF)的前6,000个常用汉字。

修改CSS

编辑 themes/Ying/assets/css/main.css

原始代码(第1-14行):

@font-face {
    font-family: 'zql';
    src: url('../font/zql-v2.woff2') format('woff2'),
        url('../font/zql-v2.woff') format('woff');
    font-display: swap;
    unicode-range: U+0000-007F,
        /* 基本拉丁字母 */
        U+4E00-9FFF,
        /* 基本汉字 */
        U+2000-206F,
        /* 通用标点符号 */
        U+3000-303F;
    /* 中文标点符号 */
}

修改为(只保留常用范围):

@font-face {
    font-family: 'zql';
    src: url('../font/zql-v2.woff2') format('woff2'),
        url('../font/zql-v2.woff') format('woff');
    font-display: swap;
    /* 只声明实际需要的Unicode范围 */
    unicode-range: 
        U+0000-007F,  /* 基本拉丁字母 */
        U+00A0-00FF,  /* 拉丁字母补充 */
        U+0100-024F,  /* 拉丁扩展 */
        U+0250-02AF,  /* IPA扩展 */
        U+0300-036F,  /* 组合变音符号 */
        U+0370-03FF,  /* 希腊字母 */
        U+0400-04FF,  /* 西里尔字母 */
        U+2000-206F,  /* 通用标点 */
        U+2070-209F,  /* 上标/下标 */
        U+20A0-20CF,  /* 货币符号 */
        U+2100-214F,  /* 字母式符号 */
        U+2150-218F,  /* 数字形式 */
        U+2190-21FF,  /* 箭头 */
        U+2200-22FF,  /* 数学运算符 */
        U+2300-23FF,  /* 杂项技术符号 */
        U+2500-257F,  /* 制表符 */
        U+2580-259F,  /* 方块元素 */
        U+25A0-25FF,  /* 几何图形 */
        U+2600-26FF,  /* 杂项符号 */
        U+2E80-2EFF,  /* CJK部首补充 */
        U+2F00-2FDF,  /* 康熙部首 */
        U+3000-303F,  /* CJK符号和标点 */
        U+3040-309F,  /* 平假名 */
        U+30A0-30FF,  /* 片假名 */
        U+3100-312F,  /* 注音符号 */
        U+3130-318F,  /* 韩文兼容字母 */
        U+3190-319F,  /* 象形文字注释 */
        U+31A0-31BF,  /* 注音字母扩展 */
        U+31C0-31EF,  /* CJK笔画 */
        U+31F0-31FF,  /* 片假名扩展 */
        U+3200-32FF,  /* 封闭式CJK文字和月份 */
        U+3300-33FF,  /* CJK兼容 */
        U+3400-4DBF,  /* CJK统一汉字扩展A */
        U+4E00-9FFF,  /* CJK统一汉字(常用) */
        U+A000-A48F,  /* 彝文音节 */
        U+A490-A4CF,  /* 彝文部首 */
        U+F900-FAFF,  /* CJK兼容汉字 */
        U+FE30-FE4F,  /* CJK兼容形式 */
        U+FF00-FFEF,  /* 半角和全角形式 */
        U+1F000-1F02F, /* 麻将牌 */
        U+1F030-1F09F, /* 多米诺骨牌 */
        U+1F0A0-1F0FF, /* 扑克牌 */
        U+1F100-1F1FF, /* 封闭式字母数字补充 */
        U+1F200-1F2FF, /* 封闭式象形文字 */
        U+1F300-1F5FF, /* 杂项符号和象形文字 */
        U+1F600-1F64F, /* 表情符号 */
        U+1F650-1F67F, /* 装饰符号 */
        U+1F680-1F6FF, /* 交通和地图符号 */
        U+1F700-1F77F, /* 炼金术符号 */
        U+1F780-1F7FF, /* 几何图形扩展 */
        U+1F800-1F8FF, /* 补充箭头C */
        U+1F900-1F9FF, /* 补充符号和象形文字 */
        U+1FA00-1FA6F, /* 棋子符号 */
        U+1FA70-1FAFF, /* 符号和象形文字扩展A */
        U+20000-2A6DF, /* CJK统一汉字扩展B */
        U+2A700-2B73F, /* CJK统一汉字扩展C */
        U+2B740-2B81F, /* CJK统一汉字扩展D */
        U+2B820-2CEAF, /* CJK统一汉字扩展E */
        U+2CEB0-2EBEF, /* CJK统一汉字扩展F */
        U+2F800-2FA1F, /* CJK兼容汉字补充 */
        U+30000-3134F; /* CJK统一汉字扩展G */
}

这样做的好处:

  • 浏览器只下载需要的字符范围
  • 不需要修改字体文件
  • 零风险

缺点:

  • 文件大小不变(仍然是1.2MB)
  • 但浏览器可能只加载部分字符(取决于实现)

方案C:使用fonttools手动限制字符范围

步骤1:创建常用字符列表

# 下载GB2312常用字符(约6,763个)
curl -o gb2312_chars.txt "https://raw.githubusercontent.com/Asarua/awesome-web/master/other/GB2312.txt"

步骤2:使用fonttools生成子集

pip install fonttools brotli

# 创建Python脚本
cat > subset_manual.py << 'EOF'
from fontTools.ttLib import TTFont
from fontTools.subset import Subsetter, Options

# 读取字符列表
with open('gb2312_chars.txt', 'r', encoding='utf-8') as f:
    chars = set(f.read().strip())

# 加载字体
font = TTFont('themes/Ying/static/font/zql-v2.woff2')

# 配置选项
options = Options()
options.flavor = 'woff2'

# 子集化
subsetter = Subsetter(options=options)
subsetter.populate(text=''.join(chars))
subsetter.subset(font)

# 保存
font.save('themes/Ying/static/font/zql-v2-subset.woff2')
print("完成!")
EOF

# 运行
python subset_manual.py

🎯 推荐方案

最简单:方案B(Unicode范围限制)

  • ✅ 不需要额外工具
  • ✅ 零风险
  • ✅ 可以立即实施
  • ⚠️ 但文件大小不会减小

效果最好:方案A(Python脚本)

  • ✅ 智能提取字符
  • ✅ 文件大小减少80%+
  • ⚠️ 需要Python环境

💡 我的建议

先尝试方案A(Python脚本):

# 1. 确保已构建Hugo
cd E:\GitHub\blog
hugo --destination=public

# 2. 安装Python依赖
pip install fonttools brotli

# 3. 运行脚本
python scripts/subset-font-safe.py

# 4. 检查结果
ls -lh themes/Ying/static/font/zql-v2-subset.*

如果方案A失败,使用方案B(Unicode范围):

  • 直接修改CSS
  • 零风险
  • 立即生效

🔄 如果所有方案都失败

保底方案: 使用原始字体,只优化JS

你已经完成了JS优化(-56%),这已经是非常显著的提升了!

# 删除失败的子集文件
rm themes/Ying/static/font/zql-v2-subset.*

# CSS保持不变(使用原始字体)
# 无需修改

文档版本: v1.0 创建时间: 2026-06-03 适用场景: glyphhanger失败时的替代方案