Inline CSS web fonts

If you serve web fonts via URL, the browser makes a separate request for every web font.

This is what the timeline looks like for a URL referenced font:

Tl body

Ready Load

Fonts included from stylesheets cause extra requests that only starts once the DOM has loaded. This causes a delay and flash of missing text or a font change flash while the fonts are loading.

However, you can avoid extra requests and rendering issues if you inline the fonts as data-uris.

Inline web fonts with this script:

# download inliner and mark it as executable
curl https://gist.githubusercontent.com/glebm/6360088/raw > inline-fonts.rb; chmod +x inline-fonts.rb
# provide URL or path to convert
./inline-fonts.rb 'https://fonts.googleapis.com/css?family=Arimo:400'

The script outputs CSS with all the url values inlined in data-uris, woff format. You can now deliver the fonts and CSS together in 1 request and the rendering is perfect, no more FOUC or font change.

There be dragons

  • base64 encoding causes a +33% file size increase, but gzip mitigates this
  • when there are more fonts files at some point it is faster to download them in parallel, depending on the font sizes and latency / bandwidth of the audience.
  • public CDN files may already be in browser cache (e.g. the most popular Google Web Fonts)
  • the most common format woff is supported everywhere but IE 8, stock Anroid Browser, and Chrome on Windows, which has a general rendering issue with some fonts, and base64 is slow on Android 2 and iOS 5. You will have to serve other formats to these browsers

Most individual font sizes are in 10 - 20 KB range; if you only use a few font files this could easily cut down initial load times by 5-20%. Measure with any client-side monitoring tool to find out (it is best if your tool shows the distribution, and not just the average).

This is what the timeline looks like once the fonts are inlined:

Tl inline

When inlined, all the fonts are finished downloading before DOMContentReady fires.

Alternatively, you could try using Google Page Speed Module, which may intellegently apply this and other optimizations, but has it's own drawbacks. SPDY should already be on for both timelines.

See also

Share on

comments powered by Disqus