文章 · 性能优化
用 unicode-range 给中文可变字体做按需加载
中文字体的问题是「字多」。常用汉字三千个起,一套完整字库轻松十几兆,整包丢给浏览器,首屏还没渲染完字体就先卡住了。unicode-range 的思路是把字库按 Unicode 区间切开,浏览器只下载页面上真正用到的那些分片。
先量清楚要付多少流量
一份 12MB 的思源黑体整包,在 4G 网络下要跑三到五秒。而首屏真正出现的汉字往往不到两百个,为了这两百个字付十几兆的代价,显然不划算。
按 Unicode 区间切片
unicode-range 是 @font-face 的描述符,用来声明「这一片只负责这些码位」。把字库按区间切成一百多个小文件后,浏览器解析 CSS 时就能算出页面实际用到的码位,只拉命中那几片。
css
@font-face {
font-family: 'SourceHanSans';
src: url('hans-012.woff2') format('woff2');
unicode-range: U+4E00-4E7F;
}顺便把字重也收掉
切片之后还有一层浪费:字重。中文可变字体一个文件就能覆盖 100 到 900 整个区间,比每个字重单独打包省得多。两者叠加时记得让切片区间保持一致,否则浏览器的字体匹配会反复回退,反而更慢。
首屏字体流量从 12MB 降到 240KB,FCP 提前了 0.9 秒。
评论9
登录后参与评论,你的发言会署上自己的名字。
123@1·2026-10-22
测试
许原作者@xuyuan·2026-10-12
放在最前面:看到都会回,先谢过各位补充的经验。
沈亦@shenyi·2026-10-14
预留尺寸这一步收益比我想的大,页面重排少了以后体感差别很明显。
韩雪松@xuesong·2026-10-15
有没有考虑过体积之外的因素?我们这边的瓶颈其实在解码那一步。
何知白@hezhibai·2026-10-16
中文按需加载这块终于有人把量化的过程写出来了,之前看到的都只给结论。
苏晚@suwan_dev·2026-10-17
我们也是这么做的,唯一想补充的是切片之后记得把字体文件放到带长缓存的路径上。
顾青@guqing·2026-10-18
对,缓存头配错的话每次访问都会重下,前面省下的全还回去了。
郑一鸣@yiming·2026-10-18
想问下这种切片方案在字体版本升级的时候怎么处理?全部重下还是只换变化的分片?
吴桐@wutong·2026-10-19
行高和字距那一段说得很实在,中文确实不能照搬西文那套参数。