字体分包,提高网页字体载入速度
编辑起因
想给博客更换一个字体, 将.ttf格式的字体文件转换成.woff2格式的字体文件并上传到云存储上,写好要注入的代码,一切准备就绪后,发现字体加载并不理想。虽然已经上传到云存储上,然而加载时还是出现了明显的等待加载的情况。
注入的代码如下:
<style>
@font-face {
font-family: "LXGW ZhiSong MN";
src: url("https://example.com/font/LXGWZhiSongMN.woff2") format("woff2");
}
body,#post-content,.markdown-body {
font-family: "LXGW ZhiSong MN",PingFang SC,Hiragino Sans GB,Droid Sans Fallback,Microsoft YaHei,sans-serif !important;
}
</style>
如下图所示,将网速限制到500KB/s模拟网络一般的情况,一份3MB的字体文件,需要6秒的加载时间,这也就导致了内容使用其他字体显示完毕后,过了6秒字体突然发生了变化,这样的效果就不太理想了。
探索
观察到大佬
/* LXGW WenKai Mono [4] */
@font-face {
font-family: 'LXGW WenKai Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('./files/lxgwwenkaimono-regular-subset-4.woff2') format('woff2');
unicode-range: U+1f1e9-1f1f5, U+1f1f7-1f1ff, U+1f21a, U+1f232, U+1f234-1f237, U+1f250-1f251, U+1f300, U+1f302-1f308, U+1f30a-1f311, U+1f315, U+1f319-1f320, U+1f324, U+1f327, U+1f32a, U+1f32c-1f32d, U+1f330-1f357, U+1f359-1f37e
}
/* LXGW WenKai Mono [5] */
@font-face {
font-family: 'LXGW WenKai Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('./files/lxgwwenkaimono-regular-subset-5.woff2') format('woff2');
unicode-range: ······
}
······
观察以上代码可以发现,一个字体文件,被拆分为若干个字体文件,并且通过unicode-range
来定义了这个哪些字符使用这个字体文件。 通过Chrome控制台的Network选项卡也能看到大量字体文件的分片被加载进来,在低网速下可以看到字符一片一片的变为新的字体。
这种方法还有一个优势在于:当一个字体文件被拆分为若干个字体分片后,由于unicode-range
定义了每个分片所对应的字符,那些未被使用到的分片就不会被加载。这样不仅提高了加载效率,也能节约网络资源,节约CDN流量,带来的浏览体验也会更好。
实践
知道了所使用的技术,不如马上来实践吧。
通过搜索,发现了中文网字计划的字体分包项目,该项目同时还提供了在线分包功能,通过浏览器可以快速进行字体的分包。不过在线分包功能是有限制的,例如无法自己指定分包文件名,而是使用默认的哈希文件名,但这除了文件名可读性变差以外,在浏览器加载上没有太大的影响。
接下来介绍在线分包与Node.js分包的步骤。
在线分包
首先进入在线分包网站,在网页左侧选择要分包的字体文件,格式方面支持otf、ttf,若有已经转换的woff2格式,也可直接选用。
选择字体文件后,点击左侧的开始分包按钮启动分包任务,只需等待数秒分包任务即可完成。分包完成后,点击右下角的“压缩下载ZIP”按钮即可打包下载分包后的字体文件。
下载后可以看到压缩文件中除了分包后的woff2字体文件、一个result.css样式表文件,还有index.html、preview.svg、reporter.json三个文件,这三个文件在实际使用中不需要用到,删除后上传剩余文件到网站后台或者云存储服务上即可。使用时只需引入result.css就可以调用对应的字体。
注意:在线分包的方式不支持一些自定义项的设置,如果想要自定义输出的分包字体文件,请看接下来的Node.js分包。
Node.js分包
首先需要电脑中已经安装Node.js,且版本大于18。关于Node.js的安装,在此不再赘述。
输入以下命令,进行全局安装
npm install cn-font-split -g
安装后,使用以下命令执行字体文件的分包。其中,-i
指定的是字体文件的路径,-o
指定的是输出目录。
cn-font-split -i=./input.ttf -o=./temp
分包的速度相较浏览器分包而言,速度有较大的提升。打开指定的输出目录,能看到与浏览器分包一样的文件,将分包后的字体文件及css样式表文件上传即可,与在线分包一致。
这种方式分包所输出的文件名为哈希值,如需自定义输出文件名,可使用以下命令(Windows命令提示符环境可能需要使用双引号):
cn-font-split -i=./input.ttf -o=./temp --renameOutputFont='ExampleFontName.[index][ext]'
使用以上命令,输出的分包文件将会以ExampleFontName.0.woff2
这样的格式命名,此处的ExampleFontName
是自定义的字符串,[index]
占位符为自增索引,[ext]
占位符为文件扩展名。
如需更多自定义的设置,可以输入cn-font-split -h
查看参数说明。更多有关信息,请访问该项目的页面。
结束
对字体文件进行了分包,当然要测试下分包后的加载效率。
同样将网速限制到500KB/s,在不使用缓存的情况下加载网页。可以看到,由于定义了css的unicode-range
参数, 一共66个字体分包,只加载了12个,总大小700KB,1.5秒就加载完成了,仅是之前6秒的四分之一,加载效率得到了很大的提升,同时也避免了字体长时间等待加载出现的“画风(字体)突变”的情况。
- 4
- 1
-
分享