CSS自定义字体及其加载优化

326 阅读5分钟

一、CSS设置自定义字体

1. 准备字体文件

首先需要获取想要使用的自定义字体文件

2. 在 CSS 中使用 @font-face 规则声明字体

@font-face {
    font-family: 'MyCustomFont'; /* 定义字体的名称,之后在其他样式中会通过这个名称来引用该字体 */
    src: url('fonts/MyCustomFont.woff2') format('woff2'); /* 指定字体文件的路径和格式,这里路径要根据实际字体文件放置位置调整 */
    /* 以下是可选属性,用于更精细地控制字体相关特性 */
    font-weight: normal; /* 定义字体的常规粗细程度,可以设置具体数值,如 400 等,也可以用关键字如 bold 等改变粗细 */
    font-style: normal; /* 定义字体的样式,如 normal(常规)、italic(斜体)等 */
}

3. 将自定义字体应用到元素上

body {
    font-family: 'MyCustomFont', sans-serif; /* 先尝试使用自定义字体 MyCustomFont,如果浏览器无法加载该字体,则使用 sans-serif 通用字体族作为备选 */
}

二、字体格式

1. 常见格式

(1)常见的字体文件格式有 TrueType(.ttf)、OpenType(.otf)、WOFF(.woff)、WOFF2(.woff2)以及 SVG 字体(.svg)等。

(2)TrueType(.ttf)历史久、应用广,基于矢量图形,可缩放且显示质量高,各操作系统支持良好,常用于日常文档编辑与简单网页设计。OpenType(.otf)源于 TrueType 并扩展,对多语言及特殊字符支持出色,排版功能更丰富,多用于专业出版、高端品牌设计等场景。 WOFF(.woff)专为网页优化,由.ttf 或.otf 压缩而来,文件小、加载快,浏览器兼容性佳,是网页引入自定义字体的常用选择。WOFF2(.woff2)是 WOFF 升级版,采用更优压缩算法,进一步缩小文件体积,适配现代网页项目。

(3)SVG 字体(.svg)基于 SVG 图形技术,可实现独特字体效果,但兼容性有限,常用于艺术创作、网页特效等特定场景。

(4)woff2已为现代大多数浏览器支持,且其体积有显著优势(ttf转化为woff2后,资源由4.9M降低至2.6M,约为原格式的53%),因此首选woff2格式

2. 格式转化

可通过cloudconvert在线平台进行5种字体格式的转化(PS:该平台也支持音/视频、图片等资源的格式转化)

image.png

三、字体压缩

通常,中文字体库动辄10M+,引入系统后,会产生资源加载慢,字体格式闪烁的问题(如图),影响用户体验。因此,字体加载优化显得尤为重要。本文中,我们将针对不同的场景给出对应的优化方案。

字体gif1.gif

1. 提取固定关键字

在一些场景中,自定义字体涉及的范围是固定的,例如活动的主题名称——“小宇宙2025年度报告”,这个时候,我们在UI提供的字体库中提取这几个字即可,可以大幅度减小字体包体积

使用fonttools工具提取字体

<!--pip为Python 包管理工具,chars.txt 里面写需要提取的字符, source.ttf 是源字体文件,最终导出文件my_font.ttf,常见格式都支持。-->
pip install fonttools
fonttools subset --text-file=chars.txt --output-file=my_font.ttf source.ttf

从字体包中提取“小宇宙2025年度报告”后,字体文件大小由10.7M缩小至12KB,加载时间缩小为原来的1/37,字体呈现较丝滑

未命名111_1736307652507.gif

注:如涉及的字体不固定,但在常用字范围内,可参考3500常用字进行提取

2. 使用字体托管平台(例:谷歌字体

image.png

如图中所示,google font提供了丰富的字体库,在线筛选后如有满意字体则可用这两种方式引入

  • 方式一:link方式
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@100..900&family=ZCOOL+KuaiLe&family=Zhi+Mang+Xing&display=swap" rel="stylesheet">
  • 方式二:import方式
<style>
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@100..900&family=ZCOOL+KuaiLe&family=Zhi+Mang+Xing&display=swap');
</style>

企业微信截图_ac3853f7-8230-4d61-8ebb-e0aba2598e23_1737446995460.png

注:(1)通过以上方式未直接引入字体包,而是利用unicode-range 属性将字体文件拆分为数百个字体包,该属性确定了所涵盖字体的unicode范围,如果页面上未出现unicode-range所包含的字符,则不加载@font-face对应src,实现了字体的按需加载,显著提升字体加载速度;(2)直接访问谷歌字体存在一定稳定性和安全风险,可参考字库分割 - 你想要的前端字体加载优化方案将分割字体托管至本地,便于项目中直接引用。

3. 自定义字体分割

适用场景:在线字体无法满足美观度要求 & 3500常用字无法覆盖业务场景,选择该方式

将UI同学提供的字体包上传至中文网字计划,操作分包,项目中引入result.css,最终字体包体积均小于100k,且能按需加载

TODO:原理,怎么做的字体切割

四、字体编辑

若部分字体显示不符合预期,则可借助字体编辑器修改/替换某一个汉字,(例如【峰】字在谷歌Zhi Mang Xing字体库中,显示为【峯】,很久很久之前,这俩是同一个字,都为峯)

image.png

方式1. 直接修改字体

将切片后的字体包(包含“峯”等的字体小文件)在字体编辑器中打开,点击编辑“峯”字后保存下载即可

image.png

方式2. 替换字体

  • 提取其他符合预期字体包中的“峰”字,操作流程参考3.1
  • 打开目标字体包切片,删除其中的“峯”字
  • 切换至编辑模式,导入字体文件——导入上述提取的“峰”
  • 切换至非编辑模式,选中“峰”字,编辑「字形信息」——unicode/命名等
  • 点选格式(ttf/woff/woff2/zip)后保存至本地,更新字体文件

参考资料