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

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

Houssein Djirdeh
Houssein Djirdeh

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

浏览器兼容性

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

字体渲染

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

  • 后备字体被替换为新字体(“无样式文本闪烁”)
  • 在页面中呈现新字体之前,系统会显示“不可见”文本(“不可见文本闪烁”)

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

可选字体

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

  • 屏蔽:呈现“不可见”文本,但在加载完成后立即切换到网页字体。
  • Swap:使用后备系统字体呈现文本,但在网页字体加载完毕后立即切换到网页字体。
  • 失败:使用后备系统字体呈现文本。

以前,指定为 font-display: optional 的字体具有 100 毫秒的阻塞期,没有交换期。这意味着,“不可见”文本会短暂显示,然后切换到后备字体。如果字体未在 100 毫秒内下载,则系统会使用后备字体,并且不会发生交换。

描绘字体加载失败的图表。
在 100 毫秒的阻塞期之后下载字体时,Chrome 中font-display: optional的先前行为

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

图表描绘了字体及时加载时,之前的可选字体行为。
在 100 毫秒阻塞期之前下载字体时,Chrome 中之前的 font-display: optional 行为

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

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

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

在 Chrome 中预加载可选字体可消除布局卡顿和无样式文本闪烁的可能性。这符合 CSS 字体模块级别 4 中指定的必需行为,其中可选字体不应导致重新布局,而用户代理可以延迟呈现适当的时间。

虽然不必预加载可选字体,但这样做可以大大提高在第一个渲染周期之前加载该字体的几率,尤其是在该字体尚未存储在浏览器缓存中的情况下。

总结

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