Web 字体优化
大家可能会想,Web 性能优化总是跟加载、渲染、网络请求这些大话题挂钩。但当你细心一想,Web 字体优化,真的是被很多人忽略的一个点。今天,我们来讲讲为什么你需要关心 Web 字体优化,怎么做才最有效,还有一些小窍门,让你的网站既好看又高效。
为什么要做 Web 字体优化?
好了,开始之前你可能在想,字体优化真的有那么重要吗?哎呦,告诉你,这事儿可不小。你试想一下,当你的页面加载时,尤其是带有自定义字体的页面,字体文件就成了“性能杀手”。你是不是有过这样的经历:页面加载一会儿,文字显示成了奇怪的默认字体,等到字体文件加载完成后,页面才突然“刷”成正常的字体?这就是我们常说的闪烁的未加载文本(FOIT,Flash of Invisible Text),它让用户体验直接掉价。
字体包的大小
你知道吗,现代字体文件能有多大?非常大。尤其是那些支持多语言的字体文件,可能会大得离谱。你要知道,很多字体库包含了成千上万的字形和符号,但如果你只是用到其中的几种字符集,加载整个字体文件简直是浪费。
更进一步讲,如果你使用的是例如 Roboto
、Open Sans
这类字体包,字体文件的大小可以很大,但你可能只需要其中很小一部分——只包含英文字符,或者只有常见的几种符号。这时,字体子集化(Font Subsetting)就显得尤为重要了。
MDN:你可以使用像 Google Fonts 这样的工具来精确选择你需要的字符集,减少文件体积。
@font-face {
font-family: "CustomFont";
src: url("/fonts/custom-font.woff2") format("woff2");
font-display: swap;
}
上面的代码告诉浏览器,使用 woff2
格式的字体文件,并且在字体加载完成之前,先用系统字体显示内容。
字体包缓存
字体文件不仅大,而且加载慢。别看浏览器缓存其他资源,字体文件也能缓存起来!只要你合理设置缓存策略,用户第二次访问你的页面时,就不需要重新加载字体文件,直接从缓存里取,省时又省力。
你可以在 HTTP 请求头中添加 Cache-Control
或 Expires
,来告诉浏览器,字体文件能缓存多久。比如:
Cache-Control: public, max-age=31536000, immutable
什么意思?max-age=31536000
表示缓存有效期为一年,immutable
则意味着这个字体文件不会变,所以浏览器可以放心地长期缓存。
MDN:
Cache-Control
是告诉浏览器如何缓存资源的一种方法,而max-age
就是告诉浏览器多久后才需要重新请求资源。
怎么优化 Web 字体加载?
使用原生字体
使用原生系统字体优化
This text uses the native system font, which is already optimized for font loading speed.
这里使用的是原生系统字体,已经优化了字体加载速度。
你知道你完全可以避免使用外部字体文件吗?对,你没听错,使用系统字体或者常见的无衬线字体,不光省时,还能避免加载外部字体文件带来的性能开销。
就拿 Arial
、Verdana
、Helvetica
这类系统字体来说,浏览器加载时直接取系统字体,速度飞快。而且,用户用的是 Mac、Windows,还是 Linux,字体的显示效果都差不多。真是无脑省时!
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
"Oxygen", sans-serif;
}
这些字体已经预装在用户的操作系统中,避免了字体文件的加载,简直是性能优化的“套路王”。
使用字体预加载
使用字体预加载优化
This text uses a custom font that is preloaded with the <link rel="preload"> tag, which optimizes the font loading speed.
上面使用的了预加载字体文件,从而优化了字体加载速度。
字体预加载:别等到你需要用到字体的时候再去加载!你可以告诉浏览器,“嘿,提前加载一下这几个字体,等我需要的时候就能立刻用!”这不仅能节省时间,还能让页面的渲染变得更顺滑。
<link
rel="preload"
href="/fonts/custom-font.woff2"
as="font"
type="font/woff2"
crossorigin="anonymous"
/>
这行代码告诉浏览器,“快!在页面渲染之前就把 custom-font.woff2
字体文件先加载好”,这样字体加载完成时,页面内容能迅速渲染出来。
MDN:
preload
可以提前加载你可能需要的资源,减少页面加载时的延迟。合适的预加载能大幅提高页面响应速度。
使用 font-display
如果你不想让你的文本在字体加载完成前变成一片空白,或者闪烁成奇怪的字体,font-display
就是你需要的武器!这个属性控制了浏览器在加载字体的过程中,应该怎么显示文本。
font-display: swap
:在字体加载之前,使用系统字体渲染文本。等字体加载完了,马上切换到目标字体。这种方式最常用,几乎能解决闪烁问题。font-display: fallback
:如果字体加载时间过长,就使用备用字体,直到自定义字体加载完为止。
@font-face {
font-family: "CustomFont";
src: url("/fonts/custom-font.woff2") format("woff2");
font-display: swap;
}
这里,swap
是最佳选择。它能确保在字体加载时,用户能看到文本,而不是一个空白的区域。
异步加载字体
再来一个进阶玩法——异步加载字体。你可以用 JavaScript 来异步加载字体文件,这样不仅能避免阻塞页面渲染,还能让你精准地控制字体的加载时机,达到完美的性能优化效果。比如,使用 Font Face Observer
这种库来观察字体是否加载完毕:
import FontFaceObserver from "fontfaceobserver";
const font = new FontFaceObserver("CustomFont");
font.load().then(function () {
document.documentElement.classList.add("custom-font-loaded");
});
这种方法的好处是什么?字体加载完后,你可以把它应用到页面上,而不会影响其他内容的渲染。无需等待字体文件加载完成,页面内容可以提前展示。
小测
参考文档
- 优化网页字体 :来自Web Dev,详细介绍了如何优化网页字体,包括字体预加载、字体子集化、字体缓存等策略。