Optimize font loading

Topic summary

Navigation text visibly flickers during reloads due to font swapping (FOUT). The goal is to force invisible text until the custom font loads (FOIT) for a smoother experience, especially after caching.

Context:

  • Shopify Ride theme with PT Sans Narrow as body and system sans-serif as headings in settings.
  • Custom CSS overrides --font-heading-family to “Outfit” and applies it to nav links; Google Fonts serves Outfit with font-display: block.
  • This results in nav rendering in a fallback/body font, then switching to Outfit once loaded, causing the flicker.

Definitions:

  • FOIT: Flash of Invisible Text (text hidden until webfont loads).
  • FOUT: Flash of Unstyled Text (fallback font shown, then swaps to webfont).

Evidence: A throttled network test video (linked) illustrates the sequence and flicker.

Key questions (unresolved):

  • How to reliably implement FOIT for navigation to eliminate flicker in normal conditions?
  • Why the apparent load order where theme CSS precedes custom CSS from theme settings, and whether editing theme CSS directly is required to control this behavior.

Status: No solution presented yet; optimization via Shopify CDN acknowledged but out of scope.

Summarized with AI on December 31. AI used: gpt-5.

Problem

My navigation flickers on page reloads because of unwanted changes in fonts, a cascade of FOUT.

Target

Font is loaded in the background and navigation is invisible until loaded, FOIT. Latest after the font is cached, this should be quick enough to provide a smooth user experience.

Context

  • Using the Ride theme, with
    • PT Sans Narrow as body font (theme settings)
    • System sans-serif as heading font (theme settings)
    • Custom CSS in theme settings to override --font-heading-family
:root {
  --font-heading-family: "Outfit", sans-serif;
}​
  • Outfit is loaded from Google fonts (understand this could be optimized with the Shopify CDN but that’s not the issue here), notably the font-display property is set to block

  • In the Ride theme, nav links are in the body font, which I changed to my heading font using custom CSS in the theme settings
.menu-drawer__menu-item.link,
	.header__menu-item.link {
	  font-family: var(--font-heading-family);
	  font-weight: 500;
	}​

Visualization

Using network throttling I was able to visualize the sequence, see video below.

https://cdn.shopify.com/videos/c/o/v/1768d20d22ce41dfa95f574d96d3e091.mp4

Questions

  • How can I consistently implement a FOIT experience? I realize that the throttled, non-cache experience will always be worse but in an unthrottled environment I need to avoid flickering.
  • Why does it seem that my custom CSS defined in the theme settings is loaded after the theme CSS? Is the only way to solve that to go make changes in the theme CSS directly?