通过预加载可选字体来防止布局偏移和不可见文本 (FOIT) 闪烁

从 Chrome 83 开始,您可以结合使用 link rel="preload" 和 font-display: optional ,以彻底消除布局卡顿

通过优化渲染周期,Chrome 83 消除了预加载可选字体时的布局偏移。 若要在渲染自定义字体时确保不会出现布局卡顿,最有效的方式是将 <link rel="preload">font-display: optional 结合使用。

请查看 MDN 的数据,了解最新的跨浏览器支持信息:

字体渲染

当网页上的资源动态变化,导致内容“偏移”时,就会发生布局偏移(也称重新布局)。提取和渲染网页字体可能会通过以下两种方式之一直接导致布局偏移:

  • 将后备字体切换为新字体(“闪烁无样式文字”)
  • 在网页中呈现新字体之前,一直显示“不可见”文字(“不可见文字闪烁”)

CSS font-display 属性提供了一种方式,可通过一系列不同的支持值(autoblockswapfallbackoptional)修改自定义字体的渲染行为。选择使用哪个值取决于异步加载字体的首选行为。不过,到目前为止,上述每个支持的值都可以通过上述两种方式之一触发重新布局!

可选字体

font-display 属性使用包含三个时间段的时间轴来处理需要在渲染前下载的字体:

  • Block:渲染“不可见”文本,但在加载完成后立即切换到网页字体。
  • 交换:使用回退系统字体渲染文本,但在加载完成后立即切换到网页字体。
  • 未通过:使用后备系统字体渲染文本。

以前,使用 font-display: optional 指定的字体的块周期为 100 毫秒,无交换周期。这意味着,在切换到回退字体之前,“不可见”文本的显示时间会非常短暂。如果未在 100 毫秒内下载字体,系统会使用回退字体,且不会发生交换。

显示字体加载失败时之前的可选字体行为的示意图
之前在 Chrome 中下载字体时(在 100 毫秒块周期过后)的 font-display: optional 行为

不过,如果在 100 毫秒的阻止期结束之前下载字体,则自定义字体会呈现并在网页上使用。

显示字体及时加载时之前的可选字体行为的示意图
之前在 Chrome 中下载字体时在 100 毫秒块周期之前font-display: optional 行为

无论使用的是后备字体,还是自定义字体是否及时完成加载,Chrome 都会在这两种情况下重新渲染网页两次。这会导致不可见文本的轻微闪烁,并且在渲染新字体时,布局卡顿会导致页面的部分内容移动。即使字体存储在浏览器的磁盘缓存中,也会发生这种情况,并且该字体可以在阻止期结束之前进行加载。

Chrome 83 推出了一些优化功能,旨在完全移除预加载了 <link rel="preload'> 的可选字体的第一个呈现周期。而是会在自定义字体加载完成或经过一段时间后阻止渲染。此超时期限目前设置为 100 毫秒,但在不久的将来可能会发生变化,以优化性能。

显示字体加载失败时新的预加载可选字体行为的示意图
当预加载字体并在 100 毫秒块期限之后下载字体时(在 100 毫秒块期限过后(不闪烁不可见文本)时,Chrome 中新增了 font-display: optional 行为
显示字体及时加载时新的预加载可选字体行为的示意图
当预加载字体并在 100 毫秒块周期之前(不闪烁不可见文本)时,Chrome 中新增了 font-display: optional 行为

在 Chrome 中预加载可选字体,可避免布局卡顿以及无样式文本闪烁。这与 CSS 字体模块级别 4 中指定的必需行为相符,其中可选字体绝不应导致重新布局,并且用户代理可以将渲染延迟一段合适的时间。

虽然无需预加载可选字体,但这可以极大地提高在第一个渲染周期之前加载该字体的几率,尤其是当该字体尚未存储在浏览器的缓存中时。

总结

Chrome 团队非常期待了解预加载可选字体以及这些新优化措施的体验!如果您遇到任何问题或希望提供任何功能建议,请提交问题