Case Study - Analyzing Web Font Performance

The number of websites using custom web fonts continues to grow at a rapid pace and this in turn affects the rendering speed of pages. Today we will compare some of the top web fonts and see how different delivery methods, such as serving from Google Fonts, hosting locally, and third parties, affect the overall load times.

According to the HTTP Archive, 57% of websites are now using custom fonts. Which is an 850% increase since 2011.

What are web fonts?

Web fonts are those not installed on a person's computer, thereby having to load from a web server. They are downloaded by using the CSS3 @font-face declaration and must be supported by the web browser.

The are four primary font formats that are used on the web today.

TrueType Font (TTF): Developed in the late 80's by Apple and Microsoft. It is the most common font format.

Developed in the late 80's by Apple and Microsoft. It is the most common font format. Web Open Font Format (WOFF): Font format developed in 2009 for use in web pages. WOFF is basically OpenType or TrueType with compression and additional metadata.

Font format developed in 2009 for use in web pages. WOFF is basically OpenType or TrueType with compression and additional metadata. Web Open Font Format (WOFF2): Better compression than WOFF.

Better compression than WOFF. Embedded Open Type (EOT): Compact form of OpenType fonts designed by Microsoft for use as embedded fonts on web pages.

So which one should you use? According to caniuse, 86% of browsers support the WOFF format. Only IE8 and older android mobile browsers don't support it. So the best recommendation would be to provide WOFF and WOFF2 (take advantage of extra compression) to all of the modern browsers and then fallback to a web safe font, such as Arial for the rest, which we will cover more about below.

For Intel's ClearSans, WOFF2 saves 25% in file size over WOFF. - The New Code

If you are wanting to provide a certain font to all of the browsers you would need to include TTF, WOFF, WOFF2 and EOT. This does, however, require more resources.

Here is a list of browser support for TTF, WOFF, WOFF2, and EOT.

Advantages of web fonts

There are many advantages to using web fonts. One of the biggest reasons that companies use web fonts is so that they can achieve consistent branding across different mediums. Web Fonts are scalable, zoomable, and high-DPI friendly, meaning they can be easily shown across desktops, tablet, and mobile phones no matter what the resolution. Other advantages of using web fonts are design, readability, and accessibility.

Webfonts are critical to good design, UX, and performance. - Ilya Grigorik, Web Performance Engineer at Google

Disadvantages of web fonts

The biggest disadvantage of using web fonts is that it instantly affects the overall rendering speed of your pages. If you are using a third party such as Google or Typekit, then you also have no control if their services go down. Typekit had an outage just this last month. This also adds extra HTTP requests to external resources. Generally speaking you want to keep HTTP requests to a minimum. Web fonts are also render blocking.

Fallback fonts

You always want to have a fallback font in case the third party web font host is down or the visitor is using an older browser. These are referred to as web safe fonts, which are pre-installed by many operating systems and don't use the CSS3 @font-face declaration.

According to cssfontstack.com, here are the top 5 sans-serif web safe fonts across Windows and Mac:

Font Windows Mac Arial 99.84% 98.74% Verdana 99.84% 99.1% Trebuchet MS 99.67% 97.12% Tahoma 99.95% 91.71% Arial Black 98.08% 96.22%

And here are the top 5 serif web safe fonts across Windows and Mac:

Font Windows Mac Times New Roman 99.67% 97.48% Georgia 99.4% 97.48% Palatino 99.29% 86.13% Lucida Bright 76.12% 99.64% Garamond 86.47% 49.91%

You can see a full list of web safe fonts at cssfontstack.com.

And if you are on mobile, Google fonts are supported by most of the modern mobile operating systems, including Android 2.2+ and iOS 4.2+. Since the Ice Cream Sandwich release, Roboto has been the standard typeface on Android. Since Froyo, Noto has been the standard typeface on Android for all languages not covered by Roboto. Those are the fonts you would want to use for your fallback fonts. And for iOS fonts there is a great resource over at iosfontlist.com.

CSS3 @font declaration example

Here is an example of how to use the @font declaration with Open Sans. This would be if you are providing the WOFF and WOFF2 formats.

@font-face { font-family: 'Open Sans'; src: local('Open Sans'), local('OpenSans'), url('./fonts/open-sans.woff2') format('woff2'), url('./fonts/open-sans.woff') format('woff'); }

Fallback font example

And here is an example of how to use a fallback font. So in the case that Open Sans is not available or can't be found the browser would resort to Arial next, which is a web safe font. This would take care of that other 14% of browsers as we mentioned earlier.

body { font: 18px/28px 'Open Sans',Arial,sans-serif; }

Render blocking and critical rendering path

As we discussed in our post on "10 Website Speed Test Tools for Analyzing Web Performance," CSS is by default treated as a render blocking resource. And since you are calling your web fonts with a CSS3 @font declaration this automatically means that web fonts can also be render blocking, keeping your page from loading as quickly as it could.

You need to take into consideration the critical rendering path. Google defined the critical rendering path as the sequence of steps the browser goes through to turn "the code and resources required to render the initial view of a web page" into actual pixels on the screen.

To optimize your critical rendering path and prevent render blocking you can include the CSS required for the initial rendering, typically styles for the above-the-fold content, directly in the HEAD section in the <style></style> elements. Then move the rest of your CSS to the bottom before the </body> element.

Example

You could also load your Google fonts asynchronously by using Google's Web Font Loader. Simply place the following code below in your footer.

<script type="text/javascript"> WebFontConfig = { google: { families: [ 'Open+Sans:400,700:latin' ] } }; (function() { var wf = document.createElement('script'); wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js'; wf.type = 'text/javascript'; wf.async = 'true'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(wf, s); })(); </script>

FOIT

FOIT, or Flash of Invisible Text, can be another big disadvantage when using web fonts. This is when a browser hides all text that should be styled with a custom font until that font has finished loading. This is definitely something you want to avoid when optimizing your font's performance because users will see a blank screen. This could increase your bounce rate and it hurts your branding.

Optimizing web font delivery further

1. Prioritize based on browser support

As we mentioned earlier, since 86% of all modern browsers support WOFF format, provide WOFF and WOFF2 (better compression) and then fall back to web safe font.

2. Choose only styles you need

Choose only the styles you need. This keeps the size down to a minimum. Typically most sites only need a normal style and a bold style. You can choose which styles you want over at Google Fonts.

3. Character sets

Unless you are dealing with multiple languages, make sure to keep your character sets down to a minimum.

You can also strip down fonts and remove charsets using the Font Squirrel Web Font Generator.

4. Host fonts locally or prefetch

Host your fonts locally. Many fonts are under an open source license. Open Sans is a good example of one you can host locally. If you aren't hosting locally use prefetching to Google Fonts to resolve the domain name faster. Include this in the HEAD section of your HTML:

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

Read more about prefetching.

5. Store in localStorage with Base64 encoding

You can take it even further by using a script to detect the supported font format, Base64 encoding the fonts into a single CSS file and storing them in localStorage . A browser's native cache gets flushed quite frequently, especially on mobile devices. So by saving to localStorage , the file gets cached persistently.

By deferring the loading of Web fonts and storing them in localStorage, we've avoided around 700 ms delay. - Smashing Magazine

localStorage also referred to as web storage is well supported by all browsers. Here is an example of how to load web fonts asynchronously from localStorage after the page has started rendering.

Another method

Here is another method in which the Filament Group had great success by using Font Face Observer. Font Face Observer is a small @font-face loader and monitor (5.2 KB minified and 1.9 KB Gzipped) and can be used with Google Fonts, Typekit, etc. They were able to decrease the time at which their font starts painting from 2.7 seconds down to 300 ms.

Read more about Font Face Observer and using Font Events.

Web font performance tests

We decided to run some comparison tests with different web fonts and techniques to see what loaded faster. We created a simple HTML page with a few paragraphs and no images. This allowed us to narrow in on font speeds without any other factors.

Google Fonts test

First we took the top 10 Google web fonts and ran them each through a test to see which one loads the fastest from Google's CDN.

Open Sans Roboto Oswald Lato Slabo 27px Droid Sans Roboto Condensed PT Sans Open Sans Condensed Source Sans Pro

Using WebPageTest, we ran tests with the following settings:

Test Location: Los Angeles

Browser: Chrome

Connection: DSL (1.5 MBps)

Number of Tests: 8 (take the median)

View: First View Only We chose first view only because any further loads would cache the font in the browser



Results

Here are the top 10 fonts and their page load times.

Font Load Time (s) ms delay compared to Open Sans Open Sans 0.476 - Oswald 0.477 1 PT Sans 0.479 3 Source Sans Pro 0.480 4 Slabo 27px 0.487 11 Roboto 0.489 12 Roboto Condensed 0.489 12 Droid Sans 0.490 13 Lato 0.497 20 Open Sans Condensed 0.503 26

They were all pretty close to each other, but as you can see Open Sans is definitely the fastest loading font, when it comes to loading from Google's CDN.

Web safe font test

Next, we ran a test using Arial, a sans-serif web safe font. We wanted to see what the difference would be if we got rid of that external request over to //fonts.googleapis.com/ .

Results

Here is a comparison of Arial vs Open Sans from Google.

Font Load Time (s) Arial (Web Safe Font) 0.281 Open Sans (Google Font) 0.476

So as you can see, there is almost a 200 ms difference between using Open Sans, calling to Google as an external resource and using Arial, a web safe font. This is good to keep in mind and realize how much latency is added simply by adding external requests and download times for fonts.

Local fonts test

Next we ran a test hosting Open Sans font locally our web server to see how it would compare to using Google's CDN and making an additional external call.

You can easily grab WOFF versions of Open Sans using the Google-Webfonts-Helper.

Results

Here is a comparison of hosting Open Sans locally vs Google CDN.

Font DOC Complete (s) Fully Loaded (s) Open Sans Local 0.530 0.706 Open Sans (Google CDN) 0.476 0.724

So as you can see hosting locally, the document complete time was actually almost 50 ms slower. But the first paint occurred at 0.347 seconds as opposed to with Google at 0.535 seconds. And it completed full load faster as well. A big reason for these results is because of the proximity of the server. The server where the content is hosted is located in Dallas TX. The test is being run from Los Angeles, CA. When using a Google Font it was being served from their CDN at this IP: 74.125.224.152 , which is located not far from the test location and it resulted in a significantly less TTFB. So CDNs do make a big difference! Hosting locally is no longer always the best solution because you want the font to be downloaded from a location in closer proximity to the user.

You can also move your Google Fonts to your CDN. We ran our own comparison between using Google's CDN and KeyCDN, and it was faster to use KeyCDN. Why? Because it reduces the number of HTTP requests, DNS lookups, lets you take advantage of a single HTTP/2 connection, and have more control over caching.

Speed Test Google CDN (ms) KeyCDN (ms) Winner WebPageTest load time 1871 ms 1815 ms KeyCDN WebPageTest fully loaded 1929 ms 1862 ms KeyCDN Pingdom load time 355 ms 324 ms KeyCDN

Third party: Typekit test

We then ran a test with Typekit to check it's performance. Typekit provides you with an advanced embed code so that you can load it asynchronously on your site. If you use their default embed code you will run into issues with FOUT, which is similar to FOIT as we described earlier, but rather it is a flash of unstyled text. Also, it is important to note that in Chrome (36+), Opera (23+), and Firefox there is a three-second timeout, after which the fallback font is shown.

Advanced Embed Code

<script type="text/javascript"> (function (d) { var config = { kitId: 'xxxxxxx', scriptTimeout: 3000 }, h = d.documentElement, t = setTimeout(function () { h.className = h.className.replace( /\bwf-loading\b/g, "") + " wf-inactive"; }, config.scriptTimeout), tk = d.createElement( "script"), f = false, s = d.getElementsByTagName("script")[0], a; h.className += " wf-loading"; tk.src = 'https://use.typekit.net/' + config.kitId + '.js'; tk.async = true; tk.onload = tk.onreadyst atechange = function () { a = this.readyState; if (f || a && a != "complete" && a != "loaded") return; f = true; clearTimeout(t); try { Typekit.load(config) } catch (e) {} }; s.parentNode.insertBefore(tk, s) })(document); </script>

Results

Here are the results from using Open Sans with Typekit.

Font Load Time (s) Open Sans (Typekit) 1.253 Open Sans (Google Font) 0.476

As you can see, not near the speed of hosting locally or using Google Fonts. One reason is that by using Typekit it instantly adds 3 HTTP requests. Also, they base64 encode all the formats for you which is nice, but it results in a "content download" time of 495 ms just for the fonts. This is why it is better to simply serve the fonts you need.

Summary

As you can see there are a lot of different ways you can improve your font performance. Two primary points you want to keep in mind are overall load times and then also first paint or render of your text, so you can avoid FOIT. Remember to run tests for 3G connections as well because mobile users might have a worse experience as opposed to desktop users.

Prioritize your font delivery based on browser support, choose only the styles and charsets you need, host with Google Fonts or locally, and experiment with storing in localStorage as well as using other methods such as Font Face Observer with font events.