Improving Font Performance with Subsetting and Local Storage

Luis Vieira
Luis Vieira
Share

A recent technique that seems to be gaining traction recently, is to use a method called subsetting to reduce the size of web fonts, encode them to base64, and store them in local storage. Web fonts if not used carefully can have a huge performance hit, and can block access to your website’s content.

This technique will allow you to reduce the size of your font files and store them asynchronously in local storage, showing a fallback system font while your fonts are being downloaded. This, along with some features inherent to local storage, allows you to have your fonts cached persistently. This means that they will stay on the client’s machine, persist across sessions, and even across a device restart.

Subsetting Your Fonts

Font subsetting is one of the most important things you can do to improve web font performance. Subsetting is nothing more than removing unused characters from the fonts files. Unused characters are normally characters from languages that you don’t use, or special characters that your website or app may not need but are often embedded in font files. By subsetting, you can potentially get up to a 50% reduction in file size.

You can use Font Squirrel’s web font generator to subset and base64 encode your fonts into one final file (be sure to choose the expert option to access custom subsetting, and select “Base64 encode” in the “CSS” section of the form).

When you’re finished, you’ll have in one stylesheet file all of your web fonts, compressed and ready for later reuse with a single request.

Choosing a Fallback Font

To avoid leaving your users waiting while the browser tries to download the font file, it’s good practice to show the user a fallback system font. This allows immediate access to the content (that’s what they’re coming for after all).

A font loading synchronously would leave the text blank while the browser waits for the font file and the user will be unable to read the content while waiting for the file download to complete.

With an asynchronous load and with a good choice of a fallback font, the user will see the text displayed in the fallback font immediately, and the font would shift to your chosen web font when the file is downloaded.

Your fallback font can be styled to make this transition softer, reducing the reflow of content. Because the user has access to your content without delay, this is an immediate improvement to the perceived performance of your site or app.

To discover the system fonts available for different OSes you can check out the following sources:

  • CSS Font Stack – A complete collection of web safe CSS font stacks for Mac and Windows.
  • iOS Fonts – Lists every font for every iOS version.

On Android, it’s more difficult to say which are the system fonts because of the number of forks and different brands using it. However, the most common fonts on Android are: Droid Serif, Droid Sans, Droid Mono, and Roboto.

Using Local Storage to Save Web Fonts

First let’s add a class to the <html> DOM node that will hold the fallback font styles. Using JavaScript, this will later be replaced with a class that has the styles of the loaded font. We will also save a path pointing to the font file to a variable for later reuse.

document.documentElement.className = 'fallback';
var css_href = '../path/fonts.css';

Next we need to check for local storage support by trying to set and get an item into local storage. Some browsers can’t store anything in private mode but window.localStorage will still return a storage object. We need this extra request to make sure that our script will work properly:

var localStorageSupported = function() {
  try {
    localStorage.setItem('test', 'test');
    localStorage.removeItem('test');
      return true;
    } catch(e) {
      return false;
    }
}

If the browser passes the localStorageSupported test and our font file is already stored, we can get the file and add it to the page header inside a style tag using the injectRawStyle() function. If the browser doesn’t pass the test, we call the injectFontsStylesheet() function on the onLoad event, so that we don’t block the ui thread:

if (localStorageSupported() && localStorage.webFonts) {
  injectRawStyle(localStorage.webFonts);
} else {
  window.onload = function() {
    injectFontsStylesheet();
  } 
}

The injectFontsStylesheet() function makes an xhr request to get the font file content, injects it into the header with the help of the injectRawStyle function and saves it to local storage:

function injectFontsStylesheet() {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', css_href, true);
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      injectRawStyle(xhr.responseText);
      localStorage.webFonts = xhr.responseText;
    }
    xhr.send();
  }
}

This is the function that creates the style tag in the head of the document and gets its content through the text parameter. It’s also at this stage that we replace the fallback class with the font class that has the web font styles:

function injectRawStyle(text) {
  var style = document.createElement('style');
  style.innerHTML = text;
  document.getElementsByTagName('head')[0].appendChild(style);
  document.documentElement.className = 'webFont';
}

Now we need the actual styles for the fallback and the web font. You can test these styles by refreshing your browser and watching the reflow of content. The goal is to try to match the fallback font styles to the real styles as much as possible, so that the perception of change becomes virtually unnoticeable.

.fallback {
  font-family: Verdana, sans-serif;
  line-height: 1.58em;
  letter-spacing: 0px;
  font-size: 9px;
} 

.webFont {
  font-family: 'Proxima-Nova', sans-serif;
  line-height: 1.3em;
  letter-spacing: 2px;
  font-size: 13px;
}

Demo and Wrap-Up

If you want to take a look at the code, you can view the JavaScript panel in the CodePen below.

See the Pen 469f4667e96cc9e89208afb7e3bfbfb2 by SitePoint (@SitePoint) on CodePen.

Note that the demo is using an external CodePen as the source CSS, as outlined on the CodePen blog.

With this solution, you’re now able to store your fonts asynchronously into local storage, while providing a good and reliable fallback font.

You can keep experimenting with this technique by trying to improve the appearance of the fallback font to match your chosen web font, or you can try to repurpose this script for other assets such as CSS or JavaScript files.

Frequently Asked Questions (FAQs) on Improving Font Performance

What is the Importance of Subsetting in Font Performance?

Subsetting is a technique used to reduce the size of a font file by removing unnecessary characters. This is particularly useful when dealing with web fonts, as it can significantly improve the loading speed of a webpage. By only including the characters that are actually used on the webpage, the size of the font file can be drastically reduced, leading to faster load times and a better user experience.

How Does Local Storage Improve Font Performance?

Local storage is a web storage method that allows web applications to store data persistently in a web browser. When it comes to fonts, local storage can be used to store font files so that they don’t have to be re-downloaded every time the webpage is loaded. This can significantly improve the performance of a webpage, especially for users with slow internet connections.

What are the Advantages of Hosting Fonts Locally?

Hosting fonts locally has several advantages. First, it eliminates the need for an additional HTTP request to an external server, which can improve load times. Second, it gives you more control over the fonts, allowing you to subset them, optimize them, and update them as needed. Finally, it can provide a performance boost, especially if your server is faster or closer to your users than the external font server.

How Can I Subset a Font for My Website?

Subsetting a font can be done using various tools and services, such as Font Squirrel’s webfont generator or Google Webfonts Helper. These tools allow you to select the characters you need and generate a subsetted font file that you can use on your website.

What are the Potential Drawbacks of Using Local Storage for Fonts?

While using local storage for fonts can improve performance, it also has some potential drawbacks. For one, it relies on the user’s browser supporting local storage, which is not always the case. Additionally, storing fonts in local storage can increase the initial load time of the webpage, as the font files need to be downloaded and stored before they can be used.

How Can I Host Fonts Locally on My Website?

Hosting fonts locally on your website involves downloading the font files, uploading them to your server, and then referencing them in your CSS. This can be done manually, or with the help of a tool or plugin, depending on your website platform.

What is the Difference Between Web Fonts and System Fonts?

Web fonts are fonts that are downloaded from the internet when a webpage is loaded, while system fonts are fonts that are already installed on the user’s device. Using system fonts can improve performance, as no download is required, but it limits your font choices to the fonts that are commonly installed on most devices.

How Can I Optimize the Performance of Web Fonts?

There are several strategies for optimizing the performance of web fonts. These include subsetting the fonts to reduce their size, hosting the fonts locally to eliminate additional HTTP requests, using local storage to avoid re-downloading the fonts, and using system fonts where possible.

What is the Impact of Fonts on Page Load Time?

Fonts can have a significant impact on page load time, especially if multiple font files are being downloaded. Each font file requires an additional HTTP request, which can slow down the loading of the webpage. Additionally, large font files can take a long time to download, especially on slow internet connections.

How Can I Use Google Web Fonts Locally?

To use Google Web Fonts locally, you can download the font files from the Google Fonts website, upload them to your server, and then reference them in your CSS. Alternatively, you can use a tool like Google Webfonts Helper to generate the necessary CSS and font files for you.