VGTech is a blog where the developers and devops of Norways most visited website share code and tricks of the trade… Read more



Are you brilliant? We're hiring. Read more

Speeding up fonts for the web

Frontend

Custom fonts for the web are a bit of a pain. Browsers support different kinds of font formats, they can be relatively heavy and the rendering can vary between operating systems.

Luckily, Google Web Fonts have come along and helped out, providing free and open-source fonts that is easy to implement on any website and should work across browsers. Typekit also provides fonts for the web, although not free.

We were having trouble getting the touch-version of VG’s front page to render correctly on Android – the reason behind this is the use of the “Times New Roman”-font. While Android does have a serif-font (Droid Serif), its metrics are not equal to that of Times New Roman, which results in text breaking at different points compared to the original font we use.

To fix this, we use the free Liberation Serif font, which is metric-compatible with Times New Roman. We did encounter a couple of issues though. Firstly, we have to insert the CSS that loads the fonts only for Android-devices. Since the front page is cached by Varnish, we can’t do a server-side conditional include, so we have to do it through Javascript. Obviously, this is not too hard, you simply check for the presence of “Android” in the user-agent string.

The problems start with the size of the font: the TTF-fonts needed for regular and bold ends up weighing a total of 281 kb. This is a lot, especially when downloading the font over a slow connection, which is often the case when using a mobile phone. Gzip’ing the fonts brings the total down to 181 kb. Including the fonts in a manner that works on all Android devices is fairly straight forward:

Show code
@font-face {
    font-style: normal;
    font-weight: normal;
    font-family: Liberation serif;
    src: url("css/LiberationSerif.ttf");
}
@font-face {
    font-style: normal;
    font-weight: bold;
    font-family: Liberation serif;
    src: url("css/LiberationSerif-Bold.ttf");
}
.someClass {
    font-family: "Liberation serif", "Times New Roman", serif;
}

The custom font loading introduced a new problem, however: While the fonts are being loaded, all the text using the font is invisible. While this might be acceptable for a couple of headers, it is not acceptable for the entire front page, especially when the download might take 20 seconds on a slow connection. We tried preloading the fonts through Javascript and hooking up an onload-event which would switch the font-family, but none of the preload-methods seemed to work.

It occured to us that if we could embed the actual font data inside the stylesheet, we would be certain that the font is actually loaded before the rule defining the font-family for the text is actually parsed by the browser. So, base64-encode the fonts, put them inline:

Show code
@font-face {
    font-style: normal;
    font-weight: normal;
    font-family: Liberation serif;
    src: url(data:font/truetype;base64,<data>) format('truetype');
}

.someClass {
    font-family: 'Liberation serif', 'Times New Roman', serif;
}

Voila! A side-effect is being able to serve both fonts in the same file, which cuts down on the number of server requests.

To further reduce the file size, we reduced the number of glyphs in the font – this cut the size of each font in half. The end size for the stylesheet containing the two fonts and the actual font-family declaration ended up at 73KB, gzipped – a significant improvement from the original 281KB.

Developer at VG with a passion for Javascript, PHP and the Android platform. @rexxars


0 comments

    Leave your comment