前端网页字体优化指南

平常开发网页常常会使用一些特殊字体,好比思源黑体、苹方字体等,由于这些字体在通常的宿主环境中是不存在的,须要经过 css 的 @font-face 定义,并从服务器中加载对应的字体文件,而字体文件通常都是比较大的,甚至有时候一个字体比其余全部的资源(js、css、图片)加起来还要大,对网页的加载性能起到很是关键的影响,所以有必要对字体进行一些优化。 本文主要从字体格式、按需提取、统一渲染三个方面来谈谈优化字体的经常使用技巧。javascript

转换字体格式

如今是 1202 年了,各主流设备基本都支持 woff2 字体格式,所以网站中没有必要再引入多种不一样格式的字体了。通常地,建议只引入 woff2 就行了,既能够保持代码的简洁性,又能够减小上传到你服务器的文件,何乐而不为?css

但是不少时候美术同窗只提供其余格式的字体文件给咱们,好比 TTF 或 OTF,那如何将其转换成 woff2 呢?html

  • TTF 字体转 WOFF2

TTF 字体,是苹果和 windows 都支持的一种字体,所以是美术同窗最喜欢用的。TTF 转换 WOFF2 是比较简单的,能够选择线上转换,推荐的网站有如下两个java

可是我的以为线上转换等待上传的时间比较久,并且有时候生成的文件是空白的,所以更加倾向于使用 node 库 ttf2woff2 转换。该库的周下载量达到 10w+ 的,可见好多人都会有将 tff 转换成 woff2 的需求。 使用方法也很简单:node

cat font.ttf | ttf2woff2 > font.woff2
复制代码

由于使用 了 cat 命令来提取 ttf 的内容,若是你使用的是 windows ,须要使用 git bash 或 wsl 来运行。python

  • OTF 转 WOFF2

除了 TTF ,美术同窗还常常提供 OTF 给咱们,这是微软和 Adobe 共同研发的字体,所以在 windows 平台仍是比较流行的。那如何将其转换成 WOFF2 呢?目前我尚未发现哪一个线上网站或 node 库能一步到位转换的,在 google 上搜索好几个线上转换的网站,要么转换完成后没法下载 ,要么转换下载后是个空文件,反正就是不靠谱的东西。git

通过一番折腾后,找到了一个不错的 python 库 otf2ttf,可以稳定的将 otf 转 ttf。 使用方法也比较简单,首先安装 python,而后经过 pip 安装 otf2ttf 就可使用了(pip 相似于 npm,是 python 的包管理器),不过官方的文档中示例代码应该是有一点小笔误:github

otf2ttf MyFont.ttf
复制代码

里面的 MyFont.ttf 应该是 MyFont.otf 才对,由于这个 input 应该是 OTF 类型而不是 TTF 。web

使用 python otf2ttf 生成 ttf 文件 后,就可使用上面提到的将 ttf 转换成 woff2 的方法获取到 woff2 了。ajax

关于字体转换的这里再啰嗦一下:有时候美术同窗还会提供 ttc 文件给咱们,这不是单个字体,而是将多种字体打包在一块儿了,须要从中提取出 ttf 后才能使用,能够尝试使用 TTC2TTF

按需压缩字体

通常的,尽管将字体转换成 woff2 格式,最小依然也有好几百 K ,而更多状况下会有 1-4M 左右。有时候,咱们只有少数的文字须要用到特殊字体,好比说只有 0-9 这 10 个数字用到某种特殊字体,若是把整个字体文件引入就没有必要了,比切10个图片还要大。好在有一些技术可以将 0-9 这10个数字对应的字体子集提取出来。我平时会使用 font-spider 字蜘 来提取。

首先,全局安装 font-spider:

npm install font-spider -g
复制代码

而后,新建一个 html 文件,好比文件名为 index.html ,里面用一个元素包含全部的你想要提取的文字,好比 0-9,并为这个元素定义上你想要的特殊字体:

<h1>0123456789</h1>


<style> @font-face { font-family: 'sourceHan'; src: url('./SourceHanSansCN-Regular.ttf'); font-weight: normal; font-style: normal; } h1 { font-family: 'sourceHan'; } </style>
复制代码

最后,在这个 html 文件所在的目录执行如下命令:

font-spider index.html
复制代码

这时候,原来的 SourceHanSansCN-Regular.ttf 就会被移动到 .font-spider/ 目录下,而原来位置的字体会被替换成只提取了 0-9 的字体文件。这个体积相差了好几个数量级的:

完整的字体文件大小是 10M :

image.png

只提取 0-9 10 个数字的字体文件只有 7K:

image.png

因此,若是你的网站内容是静态不变的,则建议使用 font-spider 将你所要用到的文字提取出来,这将会大大的减小字体文件的体积。

统一渲染时机

将字体转换成 WOFF2 及静态内容网站使用 font-spider 进行按需压缩,能够很好的控制字体的大小。(PS:WOFF2 字体没有必要再开启 GZIP,由于这个字体文本自己就是压缩过的)。

最后,咱们再来看看网络速度对字体内容的影响,假如你的网页所有内容都使用某种字体,CSS 定义以下:

@font-face {
  font-family: myfont;
  src: url('./myfont.woff2') format('woff2');
}


body {
  font-family: myfont;
}
复制代码

假如这个 myfont.woff2 文件大小为 4M,而网络下载速度只有 1M/s ,则加载这个字体须要 4 秒钟。这4秒期间因为尚未加载完成远程字体,浏览器会使用什么字体渲染呢?事实上,不一样的浏览器表现会不同的,如下是一些常见的桌面浏览器的表现:

  • IE:它会直接使用备用字体渲染,最后等webfont字体加载完毕后从新渲染。

  • Safari:它会一直等待webfont字体加载完毕,而且期间不会渲染字体。

  • Chrome / Firefox:它们会等待webfont字体加载,若是在3秒以内没有加载完毕,则使用备用字体渲染。最后webfont加载完毕,使用并从新渲染。

咱们须要想办法统一这些行为,比较理想的行为是:先使用系统默认字体,等到远程字体加载完成了再替换成特殊字体。借助于 WebFontLoader 能够很容易的实现这一效果。下面来看一下如何使用:

  1. 在 css 中经过 @font-face 定义一个字体:
@font-face {
  font-family: 'myfont';
  src: url('./myfont.woff2') format('woff2');
}
复制代码

注意,CSS 中只须要定义字体就行,而不要使用使用这个字休。

  1. 而后 引入 webfontloader (也能够经过 npm 安装),将你在 css 中定义的字体名称添加到 custom.families 列表中,并在 active 回调中将该字体添加到对应的元素上,代码以下:
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
<script> WebFont.load({   custom: {     families: ['myfont'],   },   classesfalse,   active() {     document.body.style.fontFamily = 'myfont';   }, }); </script>
复制代码

这样浏览器一开始就会使用默认字体渲染内容,等字体加载完成后再使用特殊字体从新渲染。

小结

关于字体优化技巧就先写到这里啦,有问题的欢迎留言交流哈。

相关文章
相关标签/搜索