If you ran your website through PageSpeed Insights, you may see a recommendation to ensure text remains visible during webfont load.
The solution is to change font-display method to swap or optional which is usually done in your cache plugin (check their documentation), by using a plugin, or by adding the font-display method in your font’s CSS. Preloading fonts can also eliminate layout shifts from optional fonts.
A quick rundown:
While fonts are downloading, browsers hide the text which creates a flash of invisible text (FOIT). By changing the font-display method to swap or optional, a system font is shown until the custom font is done downloading. The system font is then “swapped” with the custom font.
However, if your system font and custom font have different styling, it creates FOUT (flash of unstyled text) which results in a layout shift when the swap happens. This can be seen in a GIF. Size-adjust lets you adjust the font size to be the same as your custom font – so there’s no shift.
Setting your font-display method to swap or optional, then preloading critical fonts loading above the fold can take just a few minutes and should usually fix this for most WordPress sites.
1. FOIT vs. FOUT
Fonts load slowly because of their large file sizes. That’s why you may see the rest of the page download before the fonts. FOIT and FOUT can happen during the time your fonts are loading.
- FOIT (Flash Of Invisible Text) – when no fallback font is set, the browser hides the text while the custom font is downloading, creating a quick “flash” of invisible text. This is penalized by PageSpeed Insights but is usually not a big deal for users if it’s under 300ms.
- FOUT (Flash Of Unstyled Text) – when a fallback font is set but isn’t the same size as the custom font, a layout shift occurs when the fallback font is swapped with the custom font.
2. Use Font-Display Optional Or Swap
In the @font-face, you can choose from 5 font-display properties. Some cause FOIT while others cause FOUT.
Google also has a chart on this.
Font-Display Property | Action | Blocking Time |
---|---|---|
Auto | Browser decides how to handle fonts. | Browser Decides |
Block | Forces 3 second block which (causes FOIT). | Short |
Swap | Fallback font is shown until custom font is ready (causes FOUT). | None |
Fallback | Font is invisible at first, loads fallback, then swaps when custom font is ready. | Very Short |
Optional | Font is invisible at first, loads fallback, then lets browser decide if custom font should load based on the speed of the user’s connection. | Very Short |
The time your text is invisible is the “blocking period.” During the blocking period, you need to decide which font-display property to use. This determines how browsers will handle the fonts.
Here is how browsers react:
Browser | Action |
---|---|
Chrome | Will hide text for up to 3 seconds. If text is still not ready, uses a system font until font is ready. Swaps out font. |
Safari | Hides text until font is ready. |
Firefox | Will hide text for up to 3 seconds. If text is still not ready, uses a system font until font is ready. Swaps out font. |
Edge | Uses a system font until font is ready. Swaps out font. |
Change Font-Display Property Using Plugins
- WP FOFT Loader – uses Zach Leatherman’s method of critical FOFT + preload, then polyfill fallback to emulate font-display: optional. This is the best method but requires you to upload fonts and follow video instructions on the plugin page.
- Swap Google Fonts Display – install and activate. Finds Google Fonts and sets font-display to swap. Doesn’t work with dynamically injected Google Fonts via JS.
- Elementor – supports all 5 properties under Settings → Advanced → Google fonts load (see screenshot below).
- OMGF – supports all 5 properties under Settings → optimize Google fonts.
- WP Rocket – automatically adds swap upon installation.
- FlyingPress – adds swap under Fonts → display fallback fonts.
- Perfmatters – adds swap under Settings → Fonts → display swap.
- LiteSpeed Cache – supports default/swap under Page Optimization → CSS Settings → font display optimization.
- Asset CleanUp – supports all 5 properties under Settings → Google Fonts.
- SiteGround Optimizer – automatically added when web fonts optimization is on.
Using CSS
First, view the problematic font file in your PageSpeed Insights report.
Open the font’s CSS file. If it’s being injected by a plugin (the plugin name is usually shown in the font file), go to your Plugin Editor, select the plugin injecting the font, and view the CSS file.
If you still can’t find the font file, use String Locator to search for the font.
The final step is to add font-display: swap or font-display: optional.
Without Font-Display Swap:
/assets/vendor/googleapis/css2?family=Lato:wght@100
With Font-Display Swap:
/assets/vendor/googleapis/css2?family=Lato:wght@100&display=swap
@font-face {
font-family: "Lato Regular";
font-weight: 300;
font-style: normal;
src: url("fonts/Lato-Regular-BasicLatin.woff2") format("woff2");
font-display: swap;
}
3. Preload Above The Fold Fonts
Preloading fonts can fix FOIT and completely eliminate layout shifts.
But Google also says “inlining font declarations and adjusting stylesheets is a more effective approach.” Otherwise, you can just use preload.
Step 1: Host Fonts Locally
If fonts are served from third-party domains (fonts.gstatic.com or use.fontawesome.com), hosting them locally is faster without creating third-party requests and lets you preload them.
Most cache plugins can host fonts locally as well as OMGF, Perfmatters, and Elementor:
Step 2: Find High Priority Font Files
View your “avoid chaining critical requests” report in PSI to see which fonts are loaded with higher priority. Generally, only above the fold fonts should be preloaded. Copy those font files.
Step 3: Preload Font Files With CrossOrigin
Most cache plugins also support preloading as well as Pre* Party Resource Hints.
In most cases, you’ll just add the font file. In other cases, you may need to select the type (font) and select crossorigin.
Or add the code manually in your head:
<link rel='preload' href='/font.woff2' as='font' crossorigin>
*Always test your site to see how preloading impacts speed. Preloading too many resources can have a negative impact.
Now you can retest your website and hopefully “ensure text remains visible during webfont load” is green.
Cheers,
Tom