Lately, I have been interested in improving the speed of my blog. The main reason why I wanted to do that was because I love seeing the content instantly. I was checking some performance audit tools and a common sign that every tool was giving was that the way I was requesting the fonts was hurting the speed of my site.
I found two main questions needed answers to come up with a better approach:
My fonts were coming from a CDN. This is a common approach and it's very easy to integrate to any webpage because you copy paste a couple of lines and you have it working.
Using your fonts from a CDN have some implications you should be aware of:
Performance penalty because of network negotiation: DNS, TCP, TLS.
Prioritization of resources is not optimal.
The other approach is to host your fonts. - Serve your fonts assets from the same domain where your site is host -.
You don't have the disadvantages that I mentioned before and it's not a lot of work.
Once you have included your fonts in your project you need to load it into your page. You can change the behaviour of how your fonts load with the property font-display
. Depending on what you want I'll recommend you to take a look at these two options:
A couple of things worth mentioning. font-display: swap
will make your content shift from the "web-safe" font to your main font meanwhile font-display: optional
won't show any content at all.
I went for font-display: optional
because this gave the user-experience I was aiming to. My blog is full text and the glitch of font-display: swap
was really bad.
With font-display: swap
is critical to select the correct fallback. If you have a "serif" kind of font and your fallback is "Times new Roman" then it will look very funny.
Because I use gatsby with styled-components (emotion) for my blog I will show you how I self-hosted and configured my fonts:
e.g. static/fonts/Romoto.woff2
// fonts.js
import RomotoWoff from '../static/fonts/Romoto.woff'
import RomotoWff2 from '../static/fonts/Romoto.woff2'
export { InterUIWoff, InterUIWoff2 }
// globalFonts.js
import React from 'react'
import { Global, css } from '@emotion/core'
import * as fonts from './fonts'
const GlobalFonts = () => (
<Global
styles={css`
@font-face {
font-family: 'Romoto';
font-style: normal;
font-weight: 400;
font-display: optional;
src: url("${fonts.RomotoWoff2}") format('woff2'),url("${fonts.RomotoWoff}") format('woff');
}
`}
/>
)
export default GlobalFonts
// layout.js
import React from 'react'
import GlobalFonts from './globalFonts'
const Layout = ({ children }) => (
<>
<GlobalFonts />
{children}
</>
)
Layout.propTypes = {
children: PropTypes.node.isRequired,
}
export default Layout
* {
font-family: Romoto, sans-serif;
}
Self-host your fonts and think about your font-loading strategy. We should consider performance but if this means giving a non-optimal UX you should think this twice.
Docs: font-display