打开手机,点开一个网页,等三秒还没字——八成是字体在拖后腿

你肯定遇到过:手指一点,屏幕白着,两秒、三秒……终于“唰”一下全蹦出来,还带抖动。不是网卡,不是服务器慢,就是字体在那儿死扛。移动端用户没义务陪你等,他们划走比你敲完 @font-face 还快。

为什么移动端字体加载比桌面端慢得多?

桌面端连着Wi-Fi,缓存够大,浏览器也愿意“先显示、再替换”。移动端呢?信号忽强忽弱,4G都算好的,有些地方还在用3G;内存小,浏览器更保守——不少安卓浏览器干脆卡着不动,非要等字体文件彻底下完才肯画页面。

中文字体尤其要命。比如思源黑体 Regular,原始 TTF 就有 8MB,再加个 Bold、Italic,三个字重凑一块儿,光字体就占掉 20MB。这在手机上,真不是夸张——相当于让用户在地铁隧道里,靠 2G 信号下载一首 MP3。

真实案例:一个本地生活类小程序的 H5 首页,用了 3 套字体,每套两个字重。优化前,首屏渲染卡顿明显,用户经常等不到文字就关掉。我们只保留一套 WOFF2 格式的 Regular 字重,砍掉冗余字符,加载时间缩短了不少,用户往下拉的比例也明显提升。

3个方法,让字体在移动端“不卡壳”

方法1:用 font-display: swap 让内容先露脸

在 CSS 的 @font-face 规则里加这一行就够了:

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

效果很实在:浏览器立刻用系统字体把文字撑出来,等你的字体一到,悄悄换掉。用户看不到白屏,最多觉得“字变了一下”,但至少能读、能判断要不要继续看。

如果连这点闪烁都想避免,试试 font-display: optional。它会设个超时(通常 100ms 左右),超时就放弃替换。适合正文长、对排版一致性要求不高的页面,比如博客或帮助文档。

方法2:只打包页面里真正出现的字

你首页写了“欢迎来杭州吃小笼包”,却加载了含两万汉字的完整字体包?那多出来的 19995 个字,纯属躺在用户流量里睡大觉。

Glyphhangerfonttools 把字体“切片”——只留 HTML 里实际用到的字符。一个企业官网首页正文不到 400 个汉字,子集化后字体从 4.2MB 缩到 180KB,加载快得像开了倍速。

方法3:用 <link rel="preload"> 把关键字体“插队”

标题、Logo、首屏按钮用的字体,别等 CSS 解析完才想起它。直接在 HTML 的 <head> 里写:

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

注意两点:

  • 只对首屏立刻要用的字体 preloader,比如品牌名、主标题;
  • 一定要加 crossorigin 属性,否则字体跨域加载会失败(尤其是 CDN 托管时)。

你真的需要 Light / Medium / Bold / Black 全齐吗?

设计师喜欢配齐字重,但手机屏幕就那么大,Light 看起来发虚,Black 又太压人。多数情况下,Regular + Bold 就够用了——前者保阅读,后者抓重点。

还有一个省事技巧:用 CSS font-weight “假装”字重。比如 Regular 字体本身不带 Medium,但你写 font-weight: 500,浏览器会做轻微加粗。肉眼几乎看不出差别,却少下一个文件。

真实案例:一个知识付费 App 的课程页,原来用了 4 个字重。我们只留 Regular 和 Bold,其他地方统一用 font-weight: 500600 模拟。结果字体总大小少了近一半,用户反馈“页面清爽多了”,加载也顺滑不少。

移动端字体缓存:别让用户每次重下一遍

字体不是一次性用品。用户第一次加载了,第二次应该直接从本地拿。但很多人服务器没配对,或者 CDN 默认不缓存字体。

检查你字体文件的响应头,确保有:

Cache-Control: public, max-age=31536000, immutable

immutable 很关键——它告诉浏览器:“这个文件一年内不会变”。万一真要更新字体?改文件名就行,比如 fonts-v2.woff2,浏览器自然当新资源处理。

如果你用的是 Vercel、Netlify 或国内主流 CDN(如腾讯云 CDN、阿里云 CDN),进控制台搜“缓存规则”,把 .woff2 .woff 后缀加进去,缓存时间设为 1 年,顺手勾上“忽略查询参数”。

为什么 WOFF2 是移动端字体的刚需?

WOFF2 不是“听起来高级”的格式,它是实打实压缩利器:比 WOFF 小 30%~50%,比 TTF 小 70% 以上。而且 iOS 13+、Android Chrome 80+ 全支持,根本不用操心兼容性。

转换超简单:

  • Transfonter 上传字体,勾选 WOFF2,下载;
  • 如果你用 Vite,装 vite-plugin-fonts,配置里加一句 formats: ['woff2'],构建时自动转;
  • Webpack 用户,file-loaderurl-loader 配好 mimetype,也能搞定。

真实案例:一个政务类 H5 页面,原来用 TTF,单个字体 1.8MB。换成 WOFF2 后压到 450KB,弱网环境下首字渲染快了一大截,用户中途退出的情况也减少了。

今天就能做的1个操作:打开 Chrome DevTools,删掉最重的那个字体文件

打开你的网站 → 按 Cmd+Option+I(Mac)或 Ctrl+Shift+I(Win)调出开发者工具 → 切到 Network 面板 → 在筛选框输入 font → 刷新页面。

找到体积最大的那个 .woff2.ttf 文件,右键“Open in new tab”,看看它到底用在哪——是不是只在某个 banner 图里当装饰?是不是正文字体其实完全可以用系统字体替代?

如果是,今天就做三件事:

  1. 把它从 CSS 里注释掉;
  2. 用 Transfonter 把剩下那个必须用的字体转成 WOFF2;
  3. 替换 HTML 和 CSS 里的引用路径,重新部署。

做完刷新手机浏览器,感受一下——那个“等字”的几秒空白,很可能已经没了。