Hexo 字体分片加载实践

前言

知周所众,中文字体的体积实在夸张,动不动就十几 MB。再加上白嫖 CDN 的带宽本来就小,页面一加载就慢得让人头疼,首屏甚至能卡到怀疑人生。可同时,大家又都希望通过自定义字体给博客加点个性,让站点看起来更有味道。于是问题就出现了:既想保持风格,又不想让网站加载速度变成 PPT,这就必须想办法把字体优化一下。


技术原理

既然中文字体大得夸张,要优化加载速度,最核心的一步就是:把大块的 TTF 切成小巧的 WOFF2 分片。手动切肯定是不现实的,所以我们一般会借助现成的字体分片工具,它们能自动分析你需要的字符,然后生成只保留必要字形的字体文件。

常见做法就是用工具把字体拆成几个片段,比如常用汉字、扩展汉字、英文 / 数字、标点符号等等。这样浏览器遇到中文就加载中文那片,需要英文就加载英文那片,实现真正的 “按需加载”。

比如使用一些在线子集化工具。核心目的都是一样的:减少字体内容,让每个片段越小越好,然后在 CSS 里用 unicode-range 让浏览器自动选择它该加载哪一片。

最终效果就是:原本十几 MB 的字体,可能被拆成几个几十 KB 的小文件;加载速度提升明显,博客的个性化字体也保留,几乎两全其美。


在线字体分包器

alt text

项目地址 在线使用
cn-font-split 在线字体分包器

实践(以 Hexo anzhiyu 为例)

准备字体 → 上传到主题 → 写 CSS → 配置主题 → 完成。

  1. 使用在线工具生成分片字体

    将未分包的字体上传到在线字体分包器中
    点击 【点击开始字体分包】 等待分包完成后点击 【压缩下载 zip】

    alt text

    每个文件大概几十 KB,非常轻量。

  2. 将字体上传到主题目录

    把下载的分片文件 zip 放到:/source/fonts/ 中, 如果没有的话就自己建一个文件夹即可。

    最终目录示例:

    fonts/
    └── myfont/
    ├── MyFont-basic.woff2
    ├── MyFont-extA.woff2
    ├── MyFont-latin.woff2
    ├── MyFont-symbol.woff2
    └── result.css
  3. 添加自定义 css

    _config.anzhiyu.yml

    # Inject
    # 插入代码到头部 </head> 之前 和 底部 </body> 之前
    inject:
    head:
    # 自定义css
    - <link rel="stylesheet" href="/css/custom.css" media="defer" onload="this.media='all'">

    source/css/custom.css

    @import '/fonts/myfont/result.css';
  4. 在安知鱼主题中启用字体

    _config.anzhiyu.yml

    font:
    global-font-size: 16px
    code-font-size:
    font-family: "FZFW ZhuZi A YuanS D <- yourfont"
    code-font-family: MapleMono-Regular, consolas, Menlo, "PingFang SC", "Microsoft JhengHei", "Microsoft YaHei", sans-serif

这样全站都使用你刚才分片后的字体了。


效果展示

可以看到分片加载的速度非常快
alt text