Foit, Fout and Perceived Performance

As web developers, we strive to provide the highest fidelity interface and experience for users of our sites and applications as possible. From the use of responsive web design, SASS, CSS3, Flexbox and JavaScript frameworks we exercise every technique and option to bring the latest to our users. With great power comes great responsibility and that means dealing with FOIT, FOUT and providing the perception of performance to our users.

I’m Too Old for This S*!%

Back in the day, Mercury’s late-90s sites and applications utilized “system fonts”, no CSS (it just didn’t exist) and even rudimentary nav image rollovers were done with inline JavaScript. In short, life was simple.

But with the addition of custom font faces (@font-face) in CSS3 and the growth of JavaScript which added sophistication and separation of CSS documents we could build truly beautiful and sophisticated interfaces. What used to look like:

      <title>Hello World</title>
   <p>Hello World</p> 

now looks like:

    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
    <link rel="apple-touch-icon" href="apple-touch-icon.png" />
    <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png" />
    <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png" />
    <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png" />
    <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png" />
    <link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png" />
    <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png" />
    <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png" />
    <meta name="msapplication-TileImage" content="/windows-8-tile.png"/>
    <link rel="stylesheet" href="main.css" />

    <script src="/modernizr-custom.js"></script>
    <script src="/jquery-3.0.0.min.js"></script>
    <script src="/jquery-migrate-1.4.1.min.js"></script>

    <title>Hello World</title>


with even more HTTP requests in the associated CSS sheets:

@font-face {
  font-family: 'MyWebFont';
  src: url('webfont.eot'); /* IE9 Compat Modes */
  src: url('webfont.woff2') format('woff2'), /* Most current browsers */
       url('webfont.woff') format('woff'), /* Recent/modern browsers */
       url('webfont.ttf')  format('truetype'), /* Safari, Android, iOS */
       url('webfont.svg#svgFontName') format('svg'); /* Legacy iOS */

HTTP Requests and the Damage Done

As you can see, there’s a price to be paid for web fonts – additional HTTP requests separate from the HTTP request for the web page markup. Font files can be tardy in the chain of HTTP requests because of their size, an effect more pronounced on slow network connections or mobile connectivity – and simply because they come AFTER the initial page request.

An inconvenient truth web designers must deal with every day is to decide whether to show page text before the needed font files arrive, or wait for the font files, showing nothing until the text is ready to render with the required web fonts. Now we have to wrestle with things like FOIT and FOUT.

So What Is FOUT?

FOUT stands for “Flash of Unstyled Text”. FOUT is what happens if web page designers decide to display the page in full before font files arrive. FOUT is actually a special case of FOUC – Flash of Unstyled Content – in which the browser renders the entire web page briefly with default browser styles because the markup has loaded but the CSS sheet that dictates layout of the page has not. After a short time (often less than a second) when the CSS sheet does load the whole page re-flows to take on the layout defined by the CSS. This can be very disorienting to the user and at times give the impression of a broken website.

With FOUT, sooner or later page text will re-arrange into a new form when proper custom fonts have completed their download and the browser re-renders associated page text. Text often pushes around and across lines; at times this is a subtle change if the custom font is close to a default system font or can be extreme if the font is considerably different in composition. Oftentimes the page designer will try to select a “system font” that can be styled to be similar in size, weight, kerning and leading so that when the real font loads the page doesn’t shift that much.

What Is FOIT?

FOIT stands for “Flash of Invisible Text”. FOIT is the phenomenon users get when the page designer chooses to render the layout of the page but wait to place visible text until the custom fonts have loaded. From an information consumption standpoint, this leaves the page unusable for a short time; this design choice can make sense if the fidelity of information presentation is more important than quickest possible consumption. Many consider FOIT to be less jarring than FOUT since the page doesn’t not “change shape at any point” and proponents feel that users are used to waiting for images to download.

How Does Perceived Performance Fit Into the Discussion?

To a significant extent, FOUT and FOIT are not completely avoidable with modern web development technologies and user experience expectations. What is in our control is the use of mitigating techniques to make websites and applications have the appearance of a high level of performance. The term “Perceived Performance” is a measure of how quick a user thinks your site is – and that can often be as important as its true speed.

User Experience with progress bar loading

If you can get enough of a page to load quickly enough that the user can begin to accomplish what they came to your site for, they are typically indifferent to actual time it takes to download all assets. An example is a technique often implemented on long pages of continuously scrolling news stories – if the user can begin to read the first story or two in proper form before the entire page and associated files have downloaded, they consider the page downloaded and usable. By the time they scroll down the page for additional content the remaining material has loaded in the time they spent reading the first story, leaving the user with a high perception of performance.

What Can We Do About FOIT and FOUT?

Frankly, neither FOIT nor FOUT is optimal – what can we do to mitigate the problem?

Critical FOFT

Yes – this is another F-word: Flash of Faux Text. Zach Leatherman initially advocated for the use of a tiny “subsetted” font file (it contains only upper and lowercase characters from A-Z in the “normal” weight) followed by a separate request for the full font file (punctuation, non-alpha characters, different weights etc.). With this technique, the user will then see a quick “flash” between system font and web font much sooner which will be followed by a minor flash when the remainder of the web font loads. This technique is not foolproof but is a major leg up on unchecked FOIT/FOUT.

Critical FOFT with Data URIs

An extension on the Critical FOFT approach in which an inline “data URI” of an encoded set of basic glyphs is included in the page markup (the initial request). Since this request is inline it is blocking (doesn’t wait for later HTTP requests) in that the page will not render until this encoded font has been downloaded along with the rest of the page markup. Here is an example:

@font-face {
font-family: "font-name";
src: url(data: font/opentype;base64,[paste-base64-font-data-here]);
font-style: normal;
font-weight: normal;

Use of this technique is not perfect as it will result in a FOIT only in older/downline browsers/devices. Among other resources, Font Squirrel’s webfont generator will provide base 64 output for this purpose.

Further Reading

Use of either variation of Critical FOFT will significantly improve the perceived performance of your web pages and greatly reduce manifestations of both FOIT and FOUT. However, there are plenty of other approaches (more being invented every week) and F-words – I highly recommend Zach Leatherman’s post at

No Comments

Leave a Comment

Your email address will not be published. Required fields are marked *