中文字体常用汉字分割裁剪

221 阅读2分钟

GitHub Gist

在有需要使用非系统自带的中文字体的前端项目中,常常遇到中文字体过大的问题,一个字体大的 6-7 MB 甚至 10+ MB,小的也有 2-3 MB,对于有高性能需求的站点来说是不大能接受的,一种优化方法是在 Node.js 环境中对中文字体进行分割,裁剪出本项目需要的中文字符范围

前置

常用汉字:chinese.txt

常用汉字字符编码:chinese.json

注:chinese.txt 仅起到对照作用,可通过搜索查找想要的汉字在不在里面,该编码集包括了大部分常用的汉字,但仍有一些没有包括进来,如 “发簪” 的 “簪” 字就没有在里面,如果有需要,可以自行查找字符的 UniCode 编码添加进去

代码

此方法使用的库为 @konghayao/cn-font-split,关于更详细的使用可查看该库

安装

yarn add @konghayao/cn-font-split

使用

chinese.json 放到与脚本文件同级的文件夹内

import { fontSplit } from '@konghayao/cn-font-split';
import unicodeList from './chinese.json';
// import unicodeList from './chinese.json' assert { type: "json" }; // for Node.js 18+

fontSplit({
  FontPath: './YourFont.ttf',
  destFold: './build',
  testHTML: true,
  reporter: true,
  subsets: [[[32, 126], ...unicodeList.map(u => +u)]], // [32, 126] 表示要包括编码 32-126 的字符(可显示的 ASCII 字符集)
  autoChunk: false,
  renameOutputFont: 'YourFont.splitted.[index][ext]'
})

然后从 build 文件夹中取编号为 0 的字体文件即可(如 YourFont.splitted.0.ttf

字体参照通用的 CSS 写法即可(可以不需要写 unicode-range 属性):

@font-face {
  font-family: 'YourFont';
  src: url('YourFont.splitted.0.ttf');
}

扩展

使用以上原理,如果只有某几个字需要使用特殊字体,甚至可以生成只包含这几个字的字体:

fontSplit({
  ...
  subsets: [[0x767B, 0x5F55]] // "登" "录"
  ...
})

然后可以把生成的字体文件直接转化为 base64 嵌入到 CSS 中

:)