2) Font Loading : Fonts for Advanced Web Dev

2) Font Loading : Fonts for Advanced Web Dev

Prerequisite :

https://sandeepmachiraju.hashnode.dev/understanding-fonts-fonts-for-advanced-web-dev

Introduction :

I hope everyone has read the prerequisite post as it plays a major role in context-building for this blog post. Web fonts are typically huge files, and your website will take a while to load them. Different browsers handle this latency in different ways. Custom web fonts have been around for a long, but alas, there is currently no ideal solution for web browsers to load them.

But how does the browser load the font first?

How does the Font load?

Before the browser understands which font resources it needs, it must build the render tree, which depends on the DOM and CSSOM trees. Requests for fonts come much later than requests for other important resources, and the browser may be prevented from rendering text until the requested resource is obtained.

  1. The browser requests the HTML document.

  2. The browser begins parsing the HTML response and constructing the DOM.

  3. The browser discovers CSS, JS, and other resources and dispatches requests.

  4. The browser constructs the CSSOM after all of the CSS content is received and combines it with the DOM tree to construct the render tree.

    • Font requests are dispatched after the render tree indicates which font variants are needed to render the specified text on the page.
  5. The browser performs layout and paints content to the screen.

    • If the font is not yet available, the browser may not render any text pixels.

    • After the font is available, the browser paints the text pixels.

Font loading strategies :

These are two font-loading strategies used by the majority of browsers.

  1. Flash of Invisible Text (FOIT) where the text is hidden until the font is downloaded. If the font hasn't loaded after three seconds in browsers like Chrome and Firefox, the system font will be loaded. Until the font is ready to load & in Safari's case it entirely hides the text.

  2. Flash of Unstyled Text (FOUT) uses the fallback system font initially and then upgrades to the web font when it downloads. It focuses on content, although temporarily ignoring the layout. This may fail when showing a different font until the original one loads.

  3. Flash of Faux text ( FOFT), is the latest and is used to tackle the above two it is done by creating a fallback font of the same type with minimal file and loading it later on.

    More about this will be in my next blog post.

Impact of Font loading strategies on Web performance :

There are a variety of ways in which web fonts impact performance:

  1. Delayed text rendering

  2. Layout shifts: These layout shifts occur when a web font and its fallback font take up different amounts of space on the page.

  3. Blocked Rendering: When the browser encounters a render-blocking resource, it stops downloading the rest of the resources until these critical files are processed.

Overall, it is a bad experience for users too as Font loading or Font change can convey the idea of a broken website.

Best practices of Font Loading :

Preload to avoid layout shifts (External origins)

Using <link rel="preload"> will trigger a request for the WebFont early in the critical rendering path, without having to wait for the CSSOM to be created.

There are three different declarative solutions, which are all relatively new <link> types.

  • [<link rel="preload">](<https://web.dev/preload-critical-assets/>) informs the browser that a resource is needed as part of the current navigation, and that it should start getting fetched as soon as possible.

  • [<link rel="preconnect">](<https://web.dev/preconnect-and-dns-prefetch/>) informs the browser that your page intends to establish a connection to another origin, and that you'd like the process to start as soon as possible.

  • [<link rel="prefetch">](<https://web.dev/link-prefetch/>) is somewhat different from <link rel="preload"> and <link rel="preconnect">, in that it doesn't try to make something critical happen faster; instead, it tries to make something non-critical happen earlier, if there's a chance.

DNS prefetching allows the browser to perform the DNS lookups for links on a page in the background while the user browses the current page.It is attempt to resolve domain names before resources get requested.

<link rel="dns-prefetch" href="<https://fonts.googleapis.com/>" />

Read about other rel attribute values: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel

caution : preload is highly effective at making fonts discoverable early in the page load process, this comes at the cost of taking away browser resources from the loading of other resources.

Latest CSS properties

Two properties to learn :

  1. font-display property

    From MDN Docs: https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display

  2. font-face property

From MDN Docs: https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face

Simple suggestion, use font-display: swap for branding and other visually distinctive page elements; use font-display: optional for fonts used in body text.

clear picture below,

Understanding the lifetime of Font download :

the lifetime of a font download into three major periods:

  1. The first period is the font block period. During this period, if the font face is not loaded, any element attempting to use it must instead render with an invisible fallback font face. If the font face successfully loads during the block period, the font face is then used normally.

  2. The font swap period occurs immediately after the font block period. During this period, if the font face is not loaded, any element attempting to use it must instead render with a fallback font face. If the font face successfully loads during the swap period, the font face is then used normally.

  3. The font failure period occurs immediately after the font swap period. If the font face is not yet loaded when this period starts, it's marked as a failed load, causing normal font fallback. Otherwise, the font face is used normally.

You can even test it with the package https://github.com/bramstein/fontfaceobserver
It will monitor when a web font is loaded and notify you.

For most sites, these are the three strategies that will be most applicable:

  • If performance is a top priority: Use font-display: optional. This is the most "performant" approach: text render is delayed for no longer than 100ms and there is assurance that there will be no font-swap related layout shifts. However, the downside here is the web font will not be used if it arrives late.

  • If displaying text quickly is a top priority, but you want to still ensure the web font is used: Use font-display: swap but make sure to deliver the font early enough that it does not cause a layout shift. The downside of this option is the jarring shift when the font arrives late.

  • If ensuring text is displayed in a web font is a top priority: Use font-display: block but make sure to deliver the font early enough that it minimizes the delay of the text. The downside of this is the initial text display will be delayed. Note despite this deplay, it can still cause a layout shift as the text is actually drawn invisible, and the fallback font space is therefore user to reserver the space. Once the web font loads, this may require different space and hence a shift. This may, however, be a less jarring shift than font-display: swap as the text itself will not be seen to shift.

Note: Combining <link rel="preload"> with font-display: optional is the most effective way to guarantee no layout jank when rendering custom fonts.

Inline Font Declarations ( Internal or Local Fonts )

Allows the browser to discover the font declarations sooner by putting our fonts locally and using them in the HTML page as internal style tag, so the browser doesn't need to wait for the external stylesheet to download.

Conclusion :

It's difficult to give a recommended approach as it does depend on individual preferences, how important the web font is to the page and brand, and how jarring a late-arriving font can be when swapped in.

References :

https://web.dev/codelab-avoid-invisible-text/

https://web.dev/font-best-practices/#preconnect-to-critical-third-party-origins

https://www.keycdn.com/support/reduce-dns-lookups

Thank you! I hope this post is insightful! Before you go:

🤝 Connect: LinkedIn | Website
❤️ for the article
Follow / Subscribe for more “advanced web dev” articles

This post is also at Substack