站点运营

站点运营:字体加载自查,别让访客盯着空白文字等半天

字体文件往往藏在样式表里,不容易被注意到,但它直接决定首屏文字是立刻出现,还是先空白几秒。这篇从字体数量、输出格式、font-display、子集化和托管方式几个角度,整理一份可落地的字体自查清单,帮你在不牺牲排版的前提下,让文字尽快可读。

站点运营

站点运营:字体加载自查,别让访客盯着空白文字等半天

不少站点的性能自查都盯着图片和脚本,字体却常常被跳过。原因也简单:字体不是用独立标签引入的,而是藏在 CSS 的 @font-face 里;出问题时页面看起来又不至于完全打不开,只是文字先空着、或者字体突然跳一下。对访客来说,这几百毫秒到几秒的等待很直观;对搜索引擎来说,文字迟迟不渲染,也会影响它对页面主要内容的理解。

先数一数:一个页面到底加载了几套字体

打开浏览器开发者工具的 Network 面板,筛选 Font,刷新一个典型内容页。常见的意外有三种:一是引用了三四套字重,但页面实际只用了一两套;二是同时引入了中文字体和英文字体,而中文字体里本身已经包含西文字形;三是不同模板各引一套,互相不共用缓存。

先做减法通常比优化加载更快见效。把没被使用的字重和字体文件去掉,或者把字重合并到更少的文件里,能直接减少请求数量。

格式上优先 woff2

woff2 的压缩率明显好于 woff 和 ttf,目前主流浏览器都支持。检查方式很简单:看构建产物里是否还在输出 ttf、otf,或者 CSS 的 src 顺序是否把旧格式排在前面。合理的写法是先声明 woff2,再用 woff 兜底,而不是反过来。

font-display 决定文字是“先出现”还是“先消失”

默认情况下,浏览器在字体没下载完之前,可能选择不显示文字,也就是常说的 FOIT(不可见文本闪烁)。

在 @font-face 里加一行 font-display: swap,文字会先用系统字体显示,字体到位后再替换。对内容站来说,这通常比让文字空白更合适。也可以考虑 optional,让浏览器在网络较慢时干脆不替换,减少视觉跳动。选择哪种取决于你对排版一致性的要求,但至少要显式设置,别交给默认值。

中文字体尤其需要子集化

一套完整的中文字体动辄几 MB,直接全量加载,首屏体验很难好。常见做法是:

  • 按字形使用频率做子集,先加载常用字,再用 unicode-range 分段按需加载;
  • 正文优先使用系统字体栈,把自定义字体留给标题、按钮等少量文字;
  • 确实要用品牌字体时,只对首屏关键区域做子集,其余区域回退到系统字体。

系统字体栈并不等于“不做设计”,而是把下载成本降到零,在中文站点里往往是最划算的选择。

第三方字体服务与本地托管

从第三方加载字体,等于多了一次 DNS 解析和连接建立;如果对方响应慢或被拦截,页面就会跟着等。自查时确认:是否加了 preconnect;字体是否跨域并带上了正确的 CORS 响应头;是否设置了足够长的缓存时间。如果站点已经有稳定的静态资源域名,把字体放到自己服务器上,通常更容易控制。

图标字体该退场了

不少老站还在用图标字体承载小图标。它的代价是:为了几个图标加载一整套字体,而且图标未加载时可能显示成方框或乱码。换成语义清晰的 SVG,或者直接内联少量路径,既能避免额外请求,也不会被字体加载阻塞。

一份可执行的字体自查清单

  1. 统计页面上实际使用的字体家族与字重,删掉没用到的。
  2. 确认输出格式包含 woff2,并在 CSS 中优先声明。
  3. 为每个 @font-face 显式设置 font-display。
  4. 中文字体做子集化或改用系统字体栈,避免全量加载。
  5. 第三方字体加 preconnect,并检查跨域与缓存头。
  6. 用工具模拟慢速网络,观察首屏文字是否长时间空白或剧烈跳动。
  7. 移动端单独看一遍,确认字体没有拖慢首屏可读时间。

字体自查不需要一次全改完。先把没用的字重删掉、把 font-display 补上,往往就能看到明显变化。之后再考虑子集化和托管位置,逐步把首屏文字的等待时间压下来。