智睿享
白蓝主题五 · 清爽阅读
首页  > 日常经验

字体文件延迟HTML渲染的那些坑

最近在做一个企业官网改版,页面结构已经搭得差不多了,结果上线前测试时发现首页加载总有一瞬间文字是空白的,等一两秒后才突然跳出来。一开始以为是网络慢,后来反复刷新才发现,问题出在自定义字体文件上。

字体加载卡住文本显示

项目里用了几个漂亮的 .woff2 字体文件,通过 CSS 的 @font-face 引入。本想着提升一下设计质感,结果反而带来了体验问题。浏览器在加载页面时,如果设置了 font-display: auto(默认值),会先等字体文件下载完再渲染文字内容。这就导致 HTML 早就解析完了,但用户看到的还是白屏或者 fallback 字体闪现。

这种现象在移动端尤其明显。比如地铁里用4G打开网页,字体文件动辄几百KB,等它载完,用户早就划走了。

用 font-display 控制加载行为

后来查文档发现,CSS 提供了一个叫 font-display 的属性,专门解决这个问题。把它的值改成 swap,浏览器就会优先用系统字体先把文字画出来,等自定义字体下载完再替换。

@font-face {
  font-family: 'CustomFont';
  src: url('custom-font.woff2') format('woff2');
  font-display: swap;
}

加上 swap 之后,页面一打开文字立马可见,不会出现“文字消失”的诡异情况。虽然字体切换时会有轻微变化,但比干等强多了。

预加载关键字体

还有个办法是在 HTML head 里提前告诉浏览器哪些字体重要:

<link rel="preload" href="custom-font.woff2" as="font" type="font/woff2" crossorigin>

这样浏览器会在解析 CSS 前就发起请求,减少等待时间。注意一定要加 crossorigin 属性,不然某些浏览器会拒绝加载。

之前没加这个属性,字体始终无法预加载,调试了半天才发现是这个细节坑了我。

本地开发容易忽略真实环境

本地跑项目的时候,字体文件都在缓存里,加载飞快,根本看不出问题。等到部署到线上,走的是真实网络,延迟一下子暴露无遗。建议平时就用 Chrome 开发者工具的 Network 面板模拟慢速网络,比如选个 Slow 3G,能提前发现不少隐患。

有一次客户投诉说首页打不开,远程一看其实是文字全看不见,他们还以为是网站挂了。从那以后,凡是用自定义字体的项目,我都默认加上 font-display: swap。”}