perf: 完整性能优化 - JS按需加载 + 字体子集化 + 自动化

This commit is contained in:
Vaica committed 2026-06-03 13:03:17 +08:00
1 parent cbf2034f78
commit 630239960e
14 files changed
+2317 -10

No files matched your search

+283
View File
@@ -0,0 +1,283 @@
# 🔤 字体优化 - 替代方案(Unicode范围限制)
由于glyphhanger扫描了太多字符导致失败,这里提供两个替代方案:
---
## 方案A:Python脚本(推荐)✅
这个脚本更智能,只提取实际使用的字符。
### 步骤1:确保已构建Hugo
```bash
cd E:\GitHub\blog
hugo --destination=public
```
### 步骤2:安装Python依赖
```bash
pip install fonttools brotli
```
### 步骤3:运行Python脚本
```bash
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:验证生成的文件
```bash
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行):**
```css
@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;
/* 中文标点符号 */
}
```
**修改为(只保留常用范围):**
```css
@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:创建常用字符列表
```bash
# 下载GB2312常用字符(约6,763个)
curl -o gb2312_chars.txt "https://raw.githubusercontent.com/Asarua/awesome-web/master/other/GB2312.txt"
```
### 步骤2:使用fonttools生成子集
```bash
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脚本):**
```bash
# 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%),这已经是非常显著的提升了!
```bash
# 删除失败的子集文件
rm themes/Ying/static/font/zql-v2-subset.*
# CSS保持不变(使用原始字体)
# 无需修改
```
---
**文档版本:** v1.0
**创建时间:** 2026-06-03
**适用场景:** glyphhanger失败时的替代方案