Custom fonts impact layout shifting. Fix it to get a better user experience and improve SEO, including Cumulative Layout Shift (CLS).
Custom fonts impact performance through delayed text rendering and layout shifts. This is because they have to be downloaded and the layout must be repainted again. When a visible element on your website changes size or location, it might have an impact on the position of the content surrounding it. This is known as a layout shift.
Note that if a web font has not loaded, browsers typically delay text rendering.
Why do web fonts impact layout shifting?
The browser has to asynchronously download a custom web font, which frequently results in text changing in size or spacing after loading and applying new fonts. This produces a shift in the layout as fonts get updated because the layout needs to be recalculated.
What the page look like before and after rendering custom web fonts?
Compare two scenarios. One that uses system fonts (here Mac OS, SFNS System San Francisco Display), and the second that uses the custom Inter fonts.

Techniques for avoiding the layout changes brought on by the usage of web fonts
This directive, which is located in your @font-face
declaration, instructs the browser to fall back to the system font in case the web font is not accessible at the time that text is rendered (plus 100 ms). This indicates that subsequent page loads should render using the web font, as it will have been downloaded and made accessible in cache, but uncached page loads may still use the fallback font. There are other choices, as seen in the illustration below:
- block – gives the font face a short block period (3s is recommended in most cases) and an infinite swap period.
- swap – gives the font face an extremely small block period (100 ms or less is recommended in most cases) and an infinite swap period.
- fallback – gives the font face an extremely small block period (100 ms or less is recommended in most cases) and a short swap period (3s is recommended in most cases).
- optional – if the font can be loaded
immediately
, such that it’s available to be used for thefirst paint
of the text, the font is used. Otherwise, the font is treated as if its block period and swap period both expired before it finished loading. If the font is not used due to this, the user agent may choose to abort the font download or download it with a very low priority. If the user agent believes it would be useful for the user, it may avoid even starting the font download and proceed immediately to using a fallback font.
@font-face
@font-face {
font-display: optional;
font-family: "Inter";
font-style: normal;
font-weight: 200;
src: local("Inter ExtraLight"), local("Inter-ExtraLight"), url("/static/assets/fonts/Inter-ExtraLight.woff2") format("woff2"), url("/static/assets/fonts/Inter-ExtraLight.woff") format("woff");
}
Additional potential improvements
Using custom fonts isn’t something that should be avoided. However, there are consequences to rendering custom web fonts that impact SEO and the user experience. The following points can be considered for further improving the loading and rendering of fonts:
- Cumulative Layout Shift (CLS) is a Google metric that measures a user experience event and became a ranking factor in 2021. Unoptimized rendering of custom fonts may impact CLS.
Preconnect to critical third-party origins. When a
<link>
hasrel=preconnect
, it informs the browser that you want the connection to open up as soon as possible and that your page will be connecting to another site. Resources will load faster since they have already finished setting up by the time the browser requests them. This, in turn, eliminates roundtrip latency and saves time for users.Example code section for custom web fonts pulled from Google Fonts <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
- As much as possible, fetch custom fonts from a different domain or subdomain. A browser can only connect to the same host in parallel, with a maximum number of connections per host varying from 2 to 13, depending on the browser used. The browser will simply queue requests beyond a certain limit in an internal queue and process them when an active request ends and a
slot
opens up. This can be improved by serving custom fonts from a subdomain or third-party domain, e.g., a CDN. - Use
woff2
file format.woff2
uses Brotli compression, which reduces data by 30% better thanwoff
, resulting in faster speed and less data to download. Use subset fonts through the
unicode-range
directive which allows you to set a specific range of characters to be downloaded from a font (embedded using@font-face
) and made available for use on the current page. A subset font only contains a subset of the original font file’s characters, which significantly reduces the file size of a font.Example code section for custom web fonts with specifying unicode range /* latin */ @font-face { font-family: 'Inter'; font-style: normal; font-weight: 300; font-display: optional; src: url(https://fonts.gstatic.com/s/inter/v12/UcC73FwrK3iLTeHuS_fvQtMwCp50KnMa1ZL7W0Q5nw.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
- To reduce the Cumulative Layout Shift (CLS) impact even further, you can use the new
size-adjust
attribute. You may now change the scale of a web font as it loads to normalize the font sizes in the document and eliminate layout shifts when switching between fonts. - Use system fonts as a fallback for the custom web font. Example font family:
"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
Additional notes
There are cases that are worth mentioning here. They aren’t directly connected with the issue described in the article, but they may still be useful while debugging.
- Your fonts may not be loaded, but this doesn’t have to always be an issue. The reason is that the browser may decide not to load the custom fonts when they aren’t used on the page.
- When
font-display: optional;
is used with a disabled cache, then the custom fonts won’t be loaded.
Comments