字体文件OTF压缩

3,142 阅读3分钟

主要介绍了字体文件压缩的实现原理,也介绍了几种工具,如 transfonter、Fontmin 等等的处理方法。使用Fontmin.otf2ttf()将 otf 字体文件转为 ttf 字体文件,使用Fontmin.glyph提取字体文件中的文字,生成新的字体文件

项目中使用了字体文件思源黑体 SourceHanSansCN,但是这个字体文件太大了,差不多有 10M 左右,有些甚至更大。本来项目打包只有 869.6KB,加了字体文件之后,变成 8.1MB 了,太影响前端加载性能了。

常用的字体:

  1. 思源黑体 SourceHanSansCN
  2. 思源宋体 SourceHanSerifCN

压缩前字体文件:

font-1.png

1. 字体文件压缩 transfonter

找到了一个在线字体压缩网站:transfonter.org/,对字体文件进行压缩

压缩处理如下所示:将 8.36MB 的字体文件压缩到 7KB,不知道咋处理的。

应该是该字体经过了高度的子集化处理,只保留了非常有限的字符集,同时也可能采用了高效的压缩算法。

可以将字体从一种格式转换成另一种格式,例如从 OpenType (.otf) 转换为 TrueType (.ttf),或者转换为 Web 字体格式如 WOFF 或 WOFF2。WOFF2 格式特别高效,因为它使用了现代的无损压缩算法,可以大幅度减少文件大小。

压缩配置:

font-3.png

压缩后字体文件:

font-2.png

@font-face {
  font-family: "A01";
  src: url("../font/SOURCEHANSANSCN.OTF") format("truetype");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "A02";
  src: url("../font/SourceHanSansCN-Regular-Alphabetic.ttf") format("truetype");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "A03";
  src: url("../font/SourceHanSansCN-Regular-Alphabetic.woff") format("truetype");
}

使用时发现,压缩后的字体样式整体和压缩前基本一致,但是还是有些微变化的,位置向上偏移了一些,字型也瘦了一点。如果不细究的话,也是可以使用的。

2. 字体文件精简版

字体子集化:这是字体压缩中最关键的一步。由于许多字体包含了成千上万个字符,但实际在一个项目中可能只会用到其中一小部分。压缩工具可以根据提供的文本样本,仅保留需要用到的字符,从而极大地减小字体文件的大小。这种按需加载的策略避免了下载不必要的字符数据。

网上找到了思源黑体的精简版,项目地址为github.com/DeronW/mini…,下载后为SourceHanSansCN-Medium.ttf,只有 834KB

压缩字体文件:

font-4.png

使用时发现,字体、字形是一样的,就是粗细不一样

我的是 regular,下载的是 medium 加粗的。

正好我使用的几个地方正好是加粗的,也是可以接受使用的。

3. 字体压缩工具 Fontmin

上述项目中也提供了一个字体压缩工具Fontmin:第一个纯 JavaScript 字体子集化方案

但是 Fontmin只能处理 ttf 文件,不能处理 otf 文件,所以需要先将 otf 文件转换为 ttf 文件,然后再使用 Fontmin 进行压缩。

而且这种方案只能针对确定的字符集进行压缩,也就是得知道页面中需要用到哪些文字,取压缩这些固定的文字生成新文件,不能针对整个项目进行压缩。

3.1 OTF 转 ttf 文件

使用Fontmin.otf2ttf()将otf字体文件转为ttf字体文件

// 1. 安装
npm install --save-dev fontmin

// 2. 使用(fontmin.js文件)
// 引入
var Fontmin = require("fontmin");
// 初始化
const fontmin = new Fontmin()
  // 指定字体文件路径
  .src("src/assets/font/*.OTF")
  // 使用 Fontmin 的 otf2ttf 插件,将 OpenType (.otf) 字体转换为 TrueType (.ttf) 字体
  .use(Fontmin.otf2ttf())
  // 设置转换后字体文件的目标输出路径
  .dest("build/font");

fontmin.run(function (err, files) {
  if (err) {
    throw err;
  }
  console.log(`压缩完成,共处理了 ${files.length} 个文件`);
});

// 3. 运行命令
node fontmin.js

font-5.png

结果:8.4MB 的 SOURCEHANSANSCN.OTF 转换成 11.2MB 的 SOURCEHANSANSCN.ttf 文件了,文件变大了

font-6.png

3.2 glyph 压缩 ttf 文件

使用Fontmin.glyph提取字体文件中的文字,生成新的字体文件

// 新增压缩处理文件 fontminglyph.js
var Fontmin = require("fontmin");

const fontmin = new Fontmin()
  // 指定字体文件路径
  .src("build/font/*.ttf")
  // 使用 glyph 插件,根据实际使用的字符生成字体子集
  .use(
    // 字型提取插件
    Fontmin.glyph({
      // 指定需要保留的字符
      text: "天地玄黄 宇宙洪荒",
      // 是否保留 TTF 的提示信息,默认为 true
      hinting: false, // keep ttf hint info (fpgm, prep, cvt). default = true
    })
  )
  .dest("build/fonts");

fontmin.run(function (err, files) {
  if (err) {
    throw err;
  }
  console.log(`glyph压缩完成,共处理了 ${files.length} 个文件`);
});

font-7.png