Hammer Time! Squishing Fonts Into Text With Base64

June 19th, 2012 by Caleb Albritton

Ah, fonts. This binary data increases page load time, file size, the number of HTTP requests. Fonts will also cause the page to jump from a basic font to the included one when the font takes longer to load than it does to display the markup. All these hindrances, coupled with having many images, will begin to deteriorate your page’s load times. However, there’s a way to transfer your page’s custom fonts as plain text to the browser and compile them into a single request. Merging the request for multiple files into one or two requests will decrease your page’s load time and efficiency. Naturally the next question is, “How can I do this?” It’s actually very simple. There is a method for converting binary data into plain text using Base64 conversion. To quote Wikipedia in how Base64 conversion works, you can use the word “Man” as an example:

Man is TWFu. Encoded in ASCII, M, a, n are stored as the bytes 77, 97, 110, which are, in 8-bit quantities, 01001101, 01100001, 01101110 in base 2. These three bytes are joined together into a 24 bit buffer producing 010011010110000101101110. Packs of 6 bits (6 bits have a maximum of 64 different binary values) are converted into numbers (in this case, there are 4 numbers in this 24-bit string), which are then converted to their corresponding values in Base64.

Now to a normal person (read: not a programmer) that is not very simple at all, but what it means to you is that you can use a service such as Simple64 and you will get a Base64 string in return. Now, what can you do with this seemingly random bunch of characters? You can use them to make your site load faster. For example: you would normally use @font-face src: url(); property to include a font, correct? You can do this exactly the same way using a tool such as base64fonts.com. Convert your font then include it in an @font-face like so:

font-family: "Font Name";
src: url(data:application/x-font-tff;base64,add base64 here);

I suggest, for more than one font, using an @import with a CSS file that contains all of your fonts. By storing fonts this way, you don’t have to worry about a content “jump” — where the content is loaded, but then suddenly changes fonts when the font is finished downloading. However, problems do lie therein.

If you have several fonts, you may appreciate this option: downloading many fonts via a CSS file will cause your content to not appear at all until all styles are downloaded, causing a significant delay in the time it takes for the browser to render the content. However, the topic of whether or not this actually brings any site speed improvements seems to be highly debated. If you have GZip enabled in Apache when the site is served, it is zipped and sent. This would easily improve font delivery, as the font CSS will be zipped along with the CSS it’s inside. However, it’s much harder to deliver a GZip font file faster. As far as I can tell, there is very little speed improvement over standard font files unless you have multiple fonts that you would rather all load at once. In this case, fonts.css file included via an @import would be more efficient.

Thanks for reading, and go experiment on your site! No definitive benchmarks have been run — what are some of your favorite solutions?