做前端性能优化时,很多人会把注意力放在图片和脚本上,却忽略了字体文件对页面体验的影响。其实字体优化是技术SEO里很实在的一环,它直接关系到首屏渲染时间和核心网页指标,尤其是Largest Contentful Paint和Cumulative Layout Shift。如果字体加载慢或者闪烁严重,搜索引擎抓取时拿到的页面状态和用户看到的可能差很多。
早期项目里常用TTF或者OTF,这类格式没经过压缩,一个中文字体文件轻松破兆。现在主流做法是用WOFF2,它基于Brotli压缩,体积通常只有原始文件的四分之一左右。下面是个简单的Nginx配置,让服务器优先返回WOFF2:
location ~* \.(woff2?|ttf|otf|eot)$ {
expires 365d;
add_header Cache-Control "public, immutable";
types {
font/woff2 woff2;
font/woff woff;
}
}
谷歌在爬取移动端页面时,弱网环境占比不低,过大的字体直接拉低加载评分。我们之前有个客户站,把全站中文字体从OTF换成子集化WOFF2,TTFB没变,但LCP从4.2秒掉到2.1秒。
浏览器默认行为是先隐藏文字直到字体下载完,这段空白期对SEO不友好,用户也可能以为页面挂了。CSS的font-display属性可以改这个逻辑:
对内容站来说,swap最稳妥,能避免出现不可见文本期。代码示例:
@font-face {
font-family: 'MyFont';
src: url('/fonts/myfont.woff2') format('woff2');
font-display: swap;
}
要注意的是,swap会带来布局偏移,因为回退字体和正式字体尺寸不同。这就得配合size-adjust做预调整。
英文站点用完整WOFF2也才几十KB,但中文汉字上万个,全打包根本不现实。子集化就是只提取页面用到的字,常用工具是fonttools里的pyftsubset。
<pre>pyftsubset source.ttf --text="首页关于我们产品联系" --output-file=sub.ttf --flavor=woff2
如果页面是动态生成的,可以接Unicode区间,比如只保留常用3500字。下面是个对比表,看得出体积差异:
| 处理方式 | 文件大小 | 覆盖文字 |
|---|---|---|
| 原始OTF | 3.8MB | 全字库 |
| 完整WOFF2 | 1.1MB | 全字库 |
| 子集WOFF2 | 86KB | 首页用字 |
搜索引擎抓中文页时,如果字体请求超时,可能只抓到系统默认字体排版,影响对页面质量的判断。子集化后请求稳定,抓取日志里字体状态码全是200。
对首屏必定出现的字体,可以用link preload提前发请求:
<link rel="preload" href="/fonts/sub.woff2" as="font" type="font/woff2" crossorigin>
但别把所有字体都预加载,那样反而抢了主文档的带宽。我们一般只预加载logo和标题用的那一个子集。曾经有个站预加载了六七个字体,结果移动端LCP不降反升,撤掉多余预加载才恢复正常。
有些团队图省事把字体扔在第三方存储,没配CORS,跨域请求直接失败,浏览器默默用回退字体,设计稿和线上完全两样。自托管时记得加Access-Control-Allow-Origin。如果用CDN,要确认边缘节点缓存了字体且返回正确content-type,否则某些浏览器不认。
字体优化不是为了炫技,是让爬虫和用户用最少等待看到该看的内容。
跑Lighthouse看字体的block时间,再到Search Console的网页体验报告里核对CLS和LCP。服务端日志里筛字体请求,看是否有499或者超时。我们习惯在优化前后各抓一周抓取耗时均值,波动超过15%就要回头查是不是子集漏字了。
字体优化搭配合适的缓存策略,能让重复访问的用户几乎感知不到字体加载。技术SEO就是这样,把每个拖慢页面的小因素抠掉,排名和留存自然慢慢上来。
评论
加载中...