R3.06.3CJK font subsetting设计

中文字体体积大,需分片加载

别名: 汉字子集 · unicode-range 分片 · 中文字体分包 · 按需切字

概念解释

完整中文或泛中日韩字体动辄数兆到二十兆以上,远大于拉丁一套几百 KB 的量级。把它当单个文件放进页面,下载和解析会拖住整段文本的可用时刻。分片加载(subsetting / unicode-range splitting)是按码位、字频或本页实际用字切开,先送首屏用得到的那一片,其余后补。问题是体积和请求切分,不是闪烁该长成哪种样子,也不是回退与网页字体度量差多少。

机制

汉字、标点、扩展区、日韩兼容字加起来是一张巨大的字形表。解码整张表要占带宽、内存和主线程。unicode-range 让浏览器只请求当前页字符命中的那几个文件;构建时的子集化则按页面字符集或词频表生成更小的包。常见切法是:拉丁与数字一片、常用汉字一片、扩展与罕见字一片、标点与竖排字形再分。没有切分时,引擎必须等整包,或在包未到时长时间走回退——空档被体积本身拉长。

分片会换来更多请求。HTTP/2 下小文件并行通常仍优于单包巨文件;但切得过碎会把握手和排队变成新瓶颈,也让同一段文本的不同码位分时到达,造成按字换字。切分粒度要按首屏字符覆盖来定:第一片必须覆盖标题和首段真实用字,而不是按 Unicode 区块机械切开。

边界

用户系统已安装目标中文字体时,网页字体可以整包不下发,分片无收益。仅有少量汉字的界面(按钮上的两三个字)用系统字体或 SVG 往往更便宜。可变字体把字重轴叠进同一文件,可能比多字重各切一份更省,也可能因表格变大而更差,要用实测字节。邮件、EPUB、部分小程序运行时不支持 unicode-range 按需取片。离线阅读或内嵌应用若把字体打进安装包,运行时分片不是这条路径。

怎么落地

  • 构建时按页面或路由统计实际用字,生成子集;全站底包只含高频汉字,长尾字走第二片。
  • unicode-range 声明各片覆盖的码位,并为第一片加预加载,使首屏中文不必等扩展区。
  • 限制分片数量:首屏一片、全站常用一片、罕见字按需,避免每个区块一个文件。
  • 验证:冷加载看首屏中文所用文件的字节和完成时间;首段字符应在第一片内。把罕见字滚入视口时才应出现后续请求。整包体积不得再出现在首屏关键路径上。

延伸

  • 同组R3.06.1 字体加载策略决定文本闪烁形式 · R3.06.2 回退字体的度量差异造成重排
  • 相邻R3.13 字体加载与文本闪烁 · R3.04 性能预算
  • 站内检索unicode-range · subsetting · CJK font

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/R3.06.3