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.
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 '80s 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.
- Web Open Font Format (WOFF2): 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 Can I Use, 97% of browsers support the WOFF2 format. Unless you need to support old browsers, it's best to use WOFF2. WOFF 2 is the newest of the modern fonts and currently has the most browser support. Also, WOFF2 compresses about 30% better than WOFF, resulting in fewer data to download and, thus, faster performance. If you need to support older browser versions, fall back 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.
If you want 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, tablets, 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 rendered 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 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.
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.
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.