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

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

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

浏览器兼容性

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

字体渲染

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

  • 回退字体与新字体交换(“未设置样式的文本闪烁”)
  • 系统会显示“不可见”文本,直到将新字体渲染到页面中(“不可见文本闪烁”)

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

可选字体

font-display 属性使用三个时间段的时间轴来处理需要先下载才能呈现的字体:

  • 屏蔽:呈现“不可见”文本,但在 Web 字体加载完毕后立即切换到该字体。
  • 切换:使用后备系统字体渲染文本,但在 Web 字体加载完毕后立即切换到 Web 字体。
  • 失败:使用回退系统字体渲染文本。

以前,使用 font-display: optional 指定的字体具有 100 毫秒的块周期,没有换页周期。这意味着,在切换到后备字体之前,系统会非常短暂地显示“不可见”文本。如果未在 100 毫秒内下载该字体,则系统会使用回退字体,而不会发生切换。

显示字体加载失败时之前的可选字体行为的示意图
在 100 毫秒的屏蔽期过后下载字体时,Chrome 中的旧版 font-display: optional 行为

但是,如果字体在 100 毫秒的屏蔽期结束之前下载完毕,系统会在网页上呈现并使用自定义字体。

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

在上述两种情况下,无论是否使用了回退字体或自定义字体是否及时加载完毕,Chrome 都会两次重新渲染页面。这会导致不可见文本轻微闪烁,并且在渲染新字体时,会导致布局卡顿,从而移动网页的部分内容。即使字体存储在浏览器的磁盘缓存中,并且可以在屏蔽期结束之前正常加载,也会发生这种情况。

Chrome 83 中进行了优化,以完全移除使用 <link rel="preload'> 预加载的可选字体的首次渲染周期。而是会阻止渲染,直到自定义字体加载完毕或经过一段时间。此超时期限目前设为 100 毫秒,但为了优化性能,近期可能会发生变化。

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

在 Chrome 中预加载可选字体可消除布局卡顿和未设置样式的文本闪烁的可能性。这与 CSS Fonts Module Level 4 中指定的必需行为一致,其中可选字体绝不应导致重新布局,而用户代理可以延迟适当的时间来渲染。

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

总结

Chrome 团队非常期待了解您在启用这些新优化后预加载可选字体的体验!如果您遇到任何问题或想撤消任何功能建议,请提交问题