字体文件拖慢首屏:子集化与托管方式
发布时间:2026-02-13 16:46       
更新时间:2026-02-14 15:27
一个中文字体文件动辄几 MB,首屏时间被它拖慢毫不奇怪。字体的优化路径很成熟:先子集化,再选对加载与托管方式,体积能差出一个数量级。
一、先量化再动手
开发者工具的 Network 面板按类型过滤字体,看文件大小和加载耗时在整页的占比。手机端对字体下载更敏感,弱网下一个 3MB 的字体要加载十几秒,量化时切到慢速网络模拟看真实表现。格式本身也有空间:woff2 相比 ttf 通常能省一半以上体积,服务端确认对 woff2 返回了正确的 MIME 类型和压缩配置。
二、子集化:只打包用到的字
中文字体动辄几万个字形,而一个具体页面实际用到的往往只有几百到几千字,全量打包纯属浪费。用 fonttools 的 pyftsubset 做子集:
pyftsubset source.ttf --text-file=used_chars.txt --flavor=woff2 --output-file=font.subset.woff2
used_chars.txt 里放站点实际用到的全部字符,产出的文件常常从几 MB 降到几十 KB。字符表从页面和模板里提取,再把用户名等动态内容的常用字补进去,上线后定期重新生成。注意边界:用户可以自由输入的界面(评论区、编辑器)会出现子集外的字,这类位置退回系统字体栈,或者准备按需补字的方案。英文站点同样适用子集化,但中文才是收益最大的场景。
三、加载策略
font-display: swap 让浏览器先用系统字体渲染文字,web 字体下载完再替换,避免文字长时间不可见:
@font-face {
font-family: MyFont;
src: url(/fonts/font.subset.woff2) format("woff2");
font-display: swap;
}
关键字体再加一行 提前拉取。crossorigin 属性不能省,字体请求按匿名跨域模式发,漏了会重复加载两份。同一页面有多个字重时不要全量加载,先只上一两个常用的字重,其余按需。
四、托管与跨域
字体文件放到 CDN 时,CDN 侧要返回 Access-Control-Allow-Origin 响应头,部分浏览器对跨域字体会直接拒绝加载,控制台报 CORS 错误先查这里。字体属于低频更新的资源,长缓存加版本号更新即可,不必频繁刷新;子集文件名带上 hash,缓存按静态资源的一般规则配置。