【前端性能优化指南】5.4 - 字体的优化

字体

🔝 页面静态资源 | 🔙 上一站 - 图片css

有些时候,内置的字体并不能知足咱们的需求,若是咱们但愿使用一些更有设计性的字体,咱们通常会使用 @font-face 来加载字体文件:前端

@font-face {
    font-family: 'Samplefont';
    src: url(/static/samplefont.woff2) format('woff2'),
         url(/static/samplefont.woff) format('woff');
}
复制代码

然而这种方式的一大问题在于,在字体加载的期间,浏览器页面是默认不展现文本内容的。即咱们常说的 FOIT (Flash of Invisible Text)。在现代浏览器中,FOIT 持续至多 3 秒,会带来糟糕的用户体验。因此在字体这部分的性能优化中,主要关注点在于如何平滑的加载字体。下面有一些解决方案。git

1. 字体裁剪

关于字体的性能问题,不少时候来源于字体文件太大,加载耗时较长。所以,一种处理该问题的方式就是进行字体裁剪,从而为要加载的字体文件进行“瘦身”。因为一个字体库中可能会包含不少字(尤为是在中文的场景下),可是并不是每一个字都会使用到,所以能够将不须要使用到的字体剔除。github

例如,对于只须要使用数字的场景,就能够将其余无用的字都剔除,只留下数字和一些必要的标点。关于字体裁剪的工具,网上有不少,你们能够自行选择。web

2. font-display

你能够在 @font-face 中设置 font-display: swap,他可让 FOIT 的默认行为变为 FOUT (Flash of Unstyled Text),即先会使用默认字体样式展现文本,字体加载完毕后再将文本的字体样式进行替换。浏览器

@font-face {
    font-family: 'Samplefont';
    src: url(/static/samplefont.woff2) format('woff2'),
         url(/static/samplefont.woff) format('woff');
    font-display: swap;
}
复制代码

font-display 的取值包括 auto|block|swap|fallback|optional,这里详细介绍了各类值的使用场景[1]。目前(2021.6.5)该属性的兼容性应该也勉强够用缓存

3. 内联字体

咱们在上一节介绍过,可使用 base64 将图片“内联”到页面中。一样的,字体也可使用这种方式,这样就避免异步加载字体时的 FOIT 或 FOUT。咱们能够将字体文件转为 base64 的字符串,设置到 @font-face 里的 src 属性上:性能优化

@font-face {
    font-family: 'Samplefont';
    src: url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAHyoABMAAAAA4XQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABG…') format('woff2');
}
复制代码

但这种方式的局限性在于,在一个 @font-face 中只能加载加载一种字体类型。同时,与使用内联图片同样,这也会将本能够并行请求的数据量变为串行。markdown

4. 使用 CSS Font Loading API

CSS Font Loading API 是浏览器提供的,能够用来自定义控制字体加载的 API。这样你就能够在 JavaScript 中进行字体的加载,等加载完成后,再将须要应用新字体的元素设置为对应的样式,例如添加一个对应的 className。这里介绍了如何使用 CSS Font Loading API[2]app

不过目前(2021.6.5) CSS Font Loading API 也可能又兼容性问题。同时,因为一些困难也没法实现一个完美的 polyfill。所以若是想要使用相似的能力,能够考虑 Font Face Observer这个库。基本的使用方式以下:

const font = new FontFaceObserver('Samplefont');

font.load(null, 5000).then(
    () => document.documentElement.classList.add('loaded'),
    () => console.log('Font is not available')
);
复制代码
@font-face {
    font-family: 'Samplefont';
    src: url(/static/samplefont.woff2) format('woff2'),
         url(/static/samplefont.woff) format('woff');
}

body {
    font-family: sans-serif;
}

.loaded h1 {
    font-family: Samplefont, sans-serif;
    font-weight: 700;
}
复制代码

5. FOFT

在须要加载同一字体的粗体、斜体时,FOFT (Flash of Faux Text) 方法会很是有效。

首先你须要了解的是,对于一种字体,它的斜体与粗体是有专门的字符集的;与此同时,若是你指定了某种字体的粗体,但浏览器没有加载,那么你可使用 font-synthesis 属性来让浏览器帮你模拟。而当实际的粗体或斜体加载完毕后,再使用实际的字体集。

具体实践起会借助上面提到的 CSS Font Loading API 或者 Font Face Observer,实现当字体加载完毕后的样式修改。


了解完字体的优化措施你会发现,它们主要集中于 如何经过加载策略来下降甚至消除 FOIT。固然上面提到的这些策略与技术你能够组合使用,以达到所需的优化效果。

若是还想了解更多关于字体加载的问题,能够看看这篇文章里总结的各种加载策略[3],它还随文提供了相应的代码示例。

image.png

关于字体的性能优化就到这了,下面咱们会进入到页面静态资源优化的最后一站 —— 视频。

喜欢的朋友欢迎关注个人博客RSS 订阅


「性能优化」系列内容

  1. 带你全面掌握前端性能优化 🚀
  2. 如何利用缓存减小远程请求?
  3. 如何加快请求速度?
  4. 如何加速页面解析与处理?
  5. 静态资源优化的整体思路是什么?
    1. 如何针对 JavaScript 进行性能优化?
    2. 如何针对 CSS 进行性能优化?
    3. 图片虽好,但也会带来性能问题
    4. 字体也须要性能优化么?(本文)
    5. 🔜 如何针对视频进行性能优化?
  6. 如何避免运行时的性能问题?
  7. 如何经过预加载来提高性能?
  8. 尾声

目前内容已所有更新至 ✨ fe-performance-journey ✨ 仓库中,陆续会将内容同步到掘金上。若是但愿尽快阅读相关内容,也能够直接去该仓库中浏览。


参考资料

  1. Controlling Font Performance with font-display
  2. Getting started with CSS Font Loading
  3. A COMPREHENSIVE GUIDE TO FONT LOADING STRATEGIES
相关文章
相关标签/搜索