网页fontmin最小化字体解决方案(覆盖全面+文件小+极致体验)

前言

人性的网页浏览体验离不开炫酷的字体。

有时我们只需要显示一两个字、或者只有一行字,那还需要加载几 M 大小的整个字体文件吗?

解决

我们可以使用 fontmin 进行字体抽取。

官方项目:ecomfe / fontmin

安装
	yarn add -D fontmin
提取

准备好我们的字体 .ttf 完整文件,建立转换模板如下:

const Fontmin = require("fontmin");

// 自定义
const filePath = "./zhanku.ttf";
const fontName = "zhanku";
const extractText = "我是提取的字体,只有我生效";
const exportPath = "./fonts";

const fontmin = new Fontmin()
  .src(filePath)
  .use(
    Fontmin.glyph({
      text: extractText,
      hinting: false // keep ttf hint info (fpgm, prep, cvt). default = true
    })
  )
  .use(Fontmin.ttf2eot())
  .use(Fontmin.ttf2svg())
  .use(
    Fontmin.ttf2woff({
      deflate: true // deflate woff. default = false
    })
  )
  .use(
    Fontmin.css({
      fontFamily: fontName,
      base64: true
    })
  )
  .dest(exportPath);

fontmin.run();

自定义好我们的 4 个参数:

  • filePath :字体文件的位置

  • fontName :font-family 的名称,我们将在之后使用该名称来表示使用该字体

  • extractText :需要抽取的文字有哪些

  • exportPath :生成文件导出的文件夹

之后使用 node 运行即可得到字体包!

看一下生成的 .css 文件:

@font-face {
    font-family: "zhanku";
    src: url("zhanku.eot"); /* IE9 */
    src: url("zhanku.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */
    url(data:application/x-font-ttf;charset=utf-8;base64,......) format("truetype"), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
    url("zhanku.svg#zhanku") format("svg"); /* iOS 4.1- */
    font-style: normal;
    font-weight: normal;
}

如此一来我们就得到了 ie 使用的 .eot ,chrome / firefox 等使用的 base64 ,以及 .svg 格式。

使用

我们可以直接加载此 .css 文件即可使用该字体,在 Vue2 中试用如下:

<template>
  <div id="app">
    这是一段文字<br />
    我是提取的字体,只有我生效
  </div>
</template>

<style lang="scss">
@import "~@/font/fonts/zhanku.css";

#app {
  font-family: zhanku;
}
</style>

使用 ~ 作为 @import 的开头表示动态加载,无该标识将找不到该 .css 文件。

效果

已经达到了我们的需求,只有我们提取的字体生效。

看一下文件大小:

非常符合我们的预期。

使用 CDN

当然这也是能加载本站的字体了,一般情况我们的文件都是放在 cdn 上,需要给所有字体文件添加 cdn 网址前缀,可以更改 .css 生成部分配置如下:

.use(
    Fontmin.css({
      // 添加 cdn 子路径
      fontPath: "https://cdn.domain.com/subpath/",
      fontFamily: fontName,
      base64: true
    })
  )

如此一来便得到添加网址前缀的 .css 文件:

@font-face {
    font-family: "zhanku";
    src: url("https://cdn.domain.com/subpath/zhanku.eot"); /* IE9 */
    src: url("https://cdn.domain.com/subpath/zhanku.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */
    url(data:application/x-font-ttf;charset=utf-8;base64,......) format("truetype"), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
    url("https://cdn.domain.com/subpath/zhanku.svg#zhanku") format("svg"); /* iOS 4.1- */
    font-style: normal;
    font-weight: normal;
}

有关转换 css 完整选项可以查看:Generate css config

不使用 base64

当我们的文字稍长时,可能不止几 KB ,此时使用 base64 已经是不明智之选,把 base64 选项置为 false 或注释掉即可:

.use(
    Fontmin.css({
      fontFamily: fontName
      // base64: true
    })
  )

此时得到的将是各个字体文件的 .css

@font-face {
    font-family: "zhanku";
    src: url("zhanku.eot"); /* IE9 */
    src: url("zhanku.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */
    url("zhanku.woff") format("woff"), /* chrome, firefox */
    url("zhanku.ttf") format("truetype"), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
    url("zhanku.svg#zhanku") format("svg"); /* iOS 4.1- */
    font-style: normal;
    font-weight: normal;
}

总结

fontmin 虽然很厉害,但不是万能的,由于 font 文件表之间极其复杂的相互关联,转换得到的子字体将会破坏一部分关联信息(比如会影响字体竖排时的间距)。

但是从最底线来说,文件大小优化我们做到了。

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值