Because Performance Matters

Avoiding the FOIT

By Shawn MaustAugust 06, 2015

Have you ever loaded a web page, and for a moment everything was visible except for the text itself? And then, after a moment or two (or even more), the text itself finally showed up? If so, you’ve experienced what’s known as a “Flash of Invisible Text (FOIT).” Depending on the length of this disappearance of the text, FOIT has the capacity to cripple the usability of the site, and is something we should be wary of. What causes this bizarre behavior? And how can we minimize or eliminate it? We’ll take a look at those questions today.

What Causes FOIT?

Although custom web fonts are growing in popularity—and for good reasons—one of the potential downsides is experiencing FOIT. It happens when the browser has already reach its first paint, but is still loading and parsing the font(s) that should be used for text on the page. If this takes place, there are few different ways web browsers act while loading and processing the fonts.

  • IE - While the custom font is not available, IE will use a fallback font immediately, and then use the custom font whenever it becomes available.
  • Firefox, Chrome - These browser wait for a few seconds (3s) to load the custom font, and then use the fallback if needed.
  • Safari - Safari waits to display any of the text using the custom font until the font is downloaded and available. Even if it takes quite a while, Safari will patiently wait almost forever (up to 30s) before giving up and moving on.

Since invisible text negatively affects the usability of the page, we will want to avoid or minimize it as much as possible. And although the problem has the potential to be most severe in Safari, it can still happen to varying degrees in other browsers—especially if the connection is slower or the website is not well optimized.

For instance, if the site is not optimized and you have a visitor on a slower mobile connection using iOS Safari, you could end up with quite the usability disaster as the browser waits to download and parse the custom fonts. Even in the browsers that only wait a few seconds before using the fallback, this delay can still negatively affect the user’s experience of the site.

Alleviating FOIT

Ideally, the text of the site would be visible immediately, and there would be no FOIT. Of course, you could ensure this takes place by choosing to not use any custom fonts. But if we’re like the majority of sites out there, and choose to use custom fonts, is it possible to we eliminate the possibility of invisible text? The answer is yes.

How? By making sure that the fonts are only enabled after they are actually ready.

Earlier this year, the Filament Group shared the process they went through in discovering the root cause of FOIT that they were experiencing and how they eliminated it.

Here are the steps that can be taken to do the same on your site:

  1. Make sure there is a fallback font in font-family stack. Start by making sure there is a fallback font that will be used by default. Ideally this font would be similar to the final custom font, so that the reflow of the text isn’t too jarring when the custom fonts are applied.

  2. Make an additional CSS class that can be used to specify when to use the custom font. For instance, instead of using a custom font directly on a <h1> tag, we can make the custom font dependent on another class that will only be added to the <html> tag of the document when the fonts are actually ready to use. For instance:

     h1 { font-family: Helvetica, Arial, sans-serif; }
    
     .fonts-loaded h1 { font-family: 'My Custom Font'; }
    

    This allows the text to show up in the default text immediately, and then use the custom font whenever it’s ready.

  3. Utilize a Font Face loader and monitor. In conjunction with #2, we can use a JavaScript utility like Font Face Observer to check when the fonts are actually loaded. When they are, we would then add a class to the <html> tag of the document (like “.fonts-loaded” in the step above). This extra class would trigger the browser to use the CSS rules that use the custom font instead of the default.

         var observer = new FontFaceObserver('My Custom Font', {});
    
         observer.check().then(function() {
             window.document.documentElement.className += " fonts-loaded";
         });
    

    If the font never loads, the special class name will not be used on the document, and so the browser will never try to use the custom fonts associated with that class name.

  4. Utilize cookies for return visits. This final step would be to set a cookie after the fonts have loaded so that subsequent visits by the client would not need to check again if they were available. By default the browser will store them in its cache, and they should be available immediately for your pages. Then, once the cookie is set, we just need to add in our custom CSS class to the <html> tag if the cookies exists. The exact syntax will depend on the web server and the language you’re using, but here’s an example of what the opening tag of your HTML document may look like (using SSI with nginx):

     <!--# if expr="$HTTP_COOKIE=/fonts\-loaded\=true/" -->
     <html lang="en" class="no-js fonts-loaded">
     <!--# else -->
     <html lang="en" class="no-js">
     <!--# endif -->
    

Summary

Using steps like these will help us avoid the unwanted FOIT. The default text will appear immediately on the initial load, and then will be gracefully substituted once the custom font become available. Then on subsequent visits, the custom fonts will be available immediately. Yes, there a few more steps, but they enable us to not only use custom fonts, but avoide some of the pitfalls—including invisible text—that sometimes pop up along the way.

Resources