Using custom font without slowing down page load

Custom fonts are widely used nowadays to give your websites trendy look, but at the great expense of page loading speed. Each custom font has to be downloaded, initialized and applied throughout the page before browser can render anything. If you have a custom font in any CSS, anywhere on the page, most browsers (like IE) will not render anything (remain white) until the custom font is downloaded, initialized and applied. Usually custom fonts are over 300KB. As a result, they significantly slow down page load speed. See this timeline of a website that uses custom font:

image

The gray bar is the .eot font. The green vertical bar is when browser renders the page. Until that green bar, user is staring at a white page with absolutely nothing for 5.5 seconds. The .eot is the very last thing browser downloads before it can render anything on the page. Usually 5.5 second page load time is unacceptable for most websites because on an average 40% users abandon your site if it does not load in 3 seconds!

image

The above graph shows you that nearly 80% change in bounce rate for pages that have over 4 second page load time!

It is absolutely key that you maintain less than 4 sec home page load time. Browser cannot remain blank for more than 4 sec. Ideally the page should be fully loaded within 4 sec if you want to encourage users to come back to your site.

Let’s learn a trick that you can use to download custom fonts behind the scene, without preventing browser from rendering anything and then apply the font as soon as the font is downloaded. Once you apply this trick, browser will render the page before the custom font is downloaded:

image

As you see here, browser has rendered the page on 4th second before it has downloaded the custom font file. The font takes a long time to downloading. During this whole time, browser is free, content is rendered, user can scroll around. Once the font is downloaded, it is applied. It freezes from 8.5 sec till 9.5 second while it initializes the font and applies on the page.

Step 1: Create a CSS that loads the custom font

First create a css that will load the custom font and apply to the html elements. First create a IE version of the CSS:

@font-face{
  font-family:'Nikosh';
  src: url('nikosh2.eot'); /* here you go, IE */
}

p, li, input, select, div, span, em, i, b, u, strong {
    font-family: 'Nikosh', Arial, Helvetica, sans-serif;
}

IE only supports Embedded True Type font (.eot). It does not support TTF, OTF, WOFF.

Other browsers do not support .eot. So, for them, you need to use some other open format. Say you are using OTF:

@font-face{
  font-family:'Nikosh';
  src: url('nikosh2.otf') format('opentype');
}

p, li, input, select, div, span, em, i, b, u, strong {
    font-family: 'Nikosh', Arial, Helvetica, sans-serif;
}

This one IE won’t understand. So, you need two different CSS files. I understand there’s this bullet-proof font face hack which is claimed to work in all browsers. But I have tried it and it does not work in Chrome. Chrome does not understand the url(://) hack.

Step 2: Javascript to pre-cache the font file and download the CSS after font is loaded

Next step is to pre-cache the font file behind the scene so that browser is not frozen while the large custom font file downloads. You can use jQuery to download the font file.

var fontFile = jQuery.browser.msie ? '/wp-content/uploads/font/nikosh2.eot' 
    : '/wp-content/uploads/font/nikosh2.otf';
var cssFile = jQuery.browser.msie ? '/wp-content/uploads/font/nikosh2ie.css' 
    : '/wp-content/uploads/font/nikosh2nonie.css';

jQuery(document).ready(function(){
	jQuery.ajax({
	  url: fontFile,
	  beforeSend: function ( xhr ) {
		xhr.overrideMimeType("application/octet-stream");
	  }
	}).done(function (data) {
		jQuery("	")
		  .appendTo(jQuery('head'))
		  .attr({type : 'text/css', rel : 'stylesheet'})
		  .attr('href', cssFile);
	});
});

First it pre-caches the right font file based on browser version. Make sure you define the correct font file name here as you have defined in the browser specific css file. Once the file is downloaded, jQuery done will fire and then it will inject a link that tag will fetch the css. The css will refer the exact same font file, from the exact same location. So, browser will not download it again as it has just downloaded the file and cached in local cache. Thus the css will be applied immediately.

Remember, as soon as the <link> tag is added, browser will freeze and become white until the font is initialized and applied. So, you will some freezing here. As it is freezing after the page has loaded completely, user is at least looking at the page and thinks that the page has finished loading. So, the user experience is better.

Step 3: Enable static content expiration

For this to work, you must have static content expiration in the webserver. If you don’t have it then browser will not cache the font file and it will download the file again as soon as you add the <link> tag. In order to enable static content expiration, follow these steps:

  • Click on the website in IIS.
  • Click on “HTT Response Headers” icon.
  • Click on “Set Common headers” from the right side menu.
  • Turn on “Expire Web Content” and set a far future date.

image

This will turn on browser caching for all static files, not just font file.

Step 4: Set MIME type for fonts

IIS 7 or 8 does not come with MIME settings for .otf, .ttf etc font extensions. Only .eot is there. So, you need to set the MIME type for these extensions, otherwise it won’t deliver the font and browser will get a 404.3.

  • Click on the website on IIS.
  • Select “MIME Types” icons.
  • Click Add…
  • Add the .otf and .ttf extensions.
  • Set Content Type as: application/octet-stream

That should now enable custom fonts on your webserver.

Leave a Reply