不少站点的性能自查都盯着图片和脚本,字体却常常被跳過。原因也简單:字体不是用獨立标簽引入的,而是藏在 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,或者直接内联少量路径,既能避免額外請求,也不會被字体加载阻塞。
一份可执行的字体自查清單
- 統計頁面上實际使用的字体家族與字重,删掉没用到的。
- 確認輸出格式包含 woff2,並在 CSS 中優先声明。
- 為每個 @font-face 顯式設定 font-display。
- 中文字体做子集化或改用系統字体栈,避免全量加载。
- 第三方字体加 preconnect,並检查跨域與缓存头。
- 用工具模拟慢速網絡,观察首屏文字是否長時間空白或剧烈跳動。
- 移動端單獨看一遍,確認字体没有拖慢首屏可讀時間。
字体自查不需要一次全改完。先把没用的字重删掉、把 font-display 补上,往往就能看到明顯變化。之後再考虑子集化和托管位置,逐步把首屏文字的等待時間压下来。