Ensure text remains visible during webfont load

Fonts are often large files with slow load times. Some browsers hide text until the font loads, causing a flash of invisible text (FOIT).

How the Lighthouse font-display audit fails

Lighthouse flags any font URLs that may flash invisible text:

A screenshot of the Lighthouse Ensure text remains visible during webfont loads audit

How to avoid showing invisible text

The font-display API indicates how a font is displayed when used inside a font-face style. The following font-display values will tell the browser to use a system font if the custom font is not ready:

  • swap
  • optional
  • fallback

CSS Example

@font-face {
  font-family: 'Pacifico';
  font-style: normal;
  font-weight: 400;
  src: local('Pacifico Regular'), local('Pacifico-Regular'),
    url(https://fonts.gstatic.com/s/pacifico/v12/FwZY7-Qmy14u9lezJ-6H6MmBp0u-.woff2)
      format('woff2');
  font-display: swap;
}

Google Fonts Example

Add the &display=swap/&display=optional/&display=fallback parameter to the end of your Google Fonts URL:

<link
  href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap"
  rel="stylesheet"
/>

How to avoid layout shifts caused by deferred fonts

Temporarily showing a system font will replace a FOIT with a flash of unstyled text (FOUT). This improves FCP&LCP by rendering content sooner, but FOIT and FOUT will both have the same impact on CLS when the custom font replaces the temporary system font.

The CLS impact of font loading can be mitigated using preloads in conjunction with font-display: optional. However, overusing preloads can negatively impact load metrics. We recommend performing A/B testing to ensure that preloading fonts does not introduce any performance regressions.

Stack-specific guidance

Drupal

Specify @font-display when defining custom fonts in your theme.

Magento

Specify @font-display when defining custom fonts.

Resources