In the previous modules, you learned how to optimize of HTML, CSS, JavaScript,and media resources. In this module, discover some methods to optimize webfonts.
Web fonts can impact page performance at both load time and rendering time.Large font files can take a while to download and negatively affect FirstContentful Paint (FCP), while the incorrect font-display
value could causeundesirable layout shifts that contribute to a page's Cumulative Layout Shift(CLS).
Before optimizing web fonts can be discussed, knowing how they're discovered bythe browser can be helpful, so that you can understand how CSS prevents theretrieval of unnecessary web fonts in certain situations.
Discovery
A page's web fonts are defined in a style sheet using a @font-face
declaration:
@font-face { font-family: "Open Sans"; src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");}
The preceding code snippet defines a font-family
named "Open Sans"
, andtells the browser where to find the respective web font resource. To conservebandwidth, the browser does not download the web font until it is determinedthat the current page's layout needs it.
h1 { font-family: "Open Sans";}
In the preceding CSS snippet, the browser downloads the "Open Sans"
font fileas it parses an <h1>
element in the page's HTML.
preload
If your @font-face
declarations are defined in an external style sheet, thebrowser can only begin downloading them after it has downloaded the style sheet.This makes web fonts late-discovered resources—but there are ways to help thebrowser discover web fonts sooner.
You can initiate an early request for web font resources by using the preload
directive. The preload
directive makes web fonts discoverable early duringpage load, and the browser immediately begins downloading them without waitingfor the style sheet to finish downloading and parsing. The preload
directivedoes not wait until the font is needed on the page.
<!-- The `crossorigin` attribute is required for fonts—even self-hosted ones, as fonts are considered CORS resources. --><link rel="preload" as="font" href="/fonts/OpenSans-Regular-webfont.woff2" crossorigin>
Inline @font-face
declarations
You can make fonts discoverable earlier during page load by inliningrender-blocking CSS—including the @font-face
declarations—in the <head>
ofyour HTML using the <style>
element. In this case, the browser discoversweb fonts earlier in the page load, as it does not need to wait for an externalstyle sheet to download.
Inlining @font-face
declarations has an advantage over using the preload
hint, as the browser only downloads the fonts necessary to render the currentpage. This eliminates the risk of downloading unused fonts.
Download
After discovering web fonts and ensuring they are needed by the current page'slayout, the browser can download them. The number of web fonts, their encoding,and their file size can significantly affect how quickly a web font isdownloaded and rendered by the browser.
Self-host your web fonts
Web fonts can be served through third-party services, such as Google Fonts, orcan be self-hosted on your origin. When using a third-party service, your webpage needs to open a connection to the provider's domain before it can startdownloading the needed web fonts. This can delay discovery and subsequentdownloading of web fonts.
This overhead can be reduced using the preconnect
resource hint. By usingpreconnect
, you can tell the browser to open a connection to the cross-originsooner than the browser ordinarily would:
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
The preceding HTML snippet hints the browser to establish a connection tofonts.googleapis.com
and a CORS connection to fonts.gstatic.com
. Somefont providers—such as Google Fonts—serve CSS and font resources from differentorigins.
You can eliminate the need for a third-party connection by self-hosting yourweb fonts. In most cases, self-hosting web fonts is faster than downloading themfrom a cross-origin. If you plan on self-hosting web fonts, check that your siteis using a Content Delivery Network (CDN), HTTP/2 or HTTP/3, and sets thecorrect caching headers for the web fonts you need for your website.
Use WOFF2—and WOFF2 only
WOFF2 enjoys wide browser support and the best compression—up to 30% betterthan WOFF. The reduced file size leads to quicker download times. The WOFF2format is often the only one needed for full compatibility across modernbrowsers.
Subset your web fonts
Web fonts typically include a wide range of different glyphs, which are neededto represent the wide variety of characters used in different languages. If yourpage serves content in only one language—or uses a single alphabet—then you canreduce the size of your web fonts through subsetting. This often done byspecifying a number—or a range of—unicode code points.
A subset is a reduced set of the glyphs that were included in the original webfont file. For example, instead of serving all glyphs, your page might serve aspecific subset for Latin characters. Depending on the subset needed, removingglyphs can significantly reduce the size of a font file.
Some web font providers—such as Google Fonts—offer subsets automatically throughthe use of a query string parameter. For example, thehttps://fonts.googleapis.com/css?family=Roboto&subset=latin
URL serves astyle sheet with the Roboto web font that only use the Latin alphabet.
If you've decided to self-host your web fonts, the next step is to generate andhost those subsets yourself using tools such as glyphanger or subfont.
However, if you don't have the capacity to self-host your own web fonts, you cansubset web fonts provided by Google Fonts by specifying an additional text
query string parameter containing only the unicode code points necessary foryour website. For example, if you have a display web font on your site that onlyneeds a small number of characters needed for the phrase "Welcome", you canrequest that subset through Google Fonts through the following URL:https://fonts.googleapis.com/css?family=Monoton&text=Welcome
. This cansignificantly reduce the amount of web font data needed for a single typefaceon your website, if such extreme subsetting can be useful on your website.
Font rendering
After the browser has discovered and downloaded a web font, it can then berendered. By default, the browser blocks the rendering of any text that uses aweb font until the it's downloaded. You can adjust the browser's text renderingbehavior, and configure what text should be shown—or not shown—until the webfont has fully loaded using the font-display
CSS property.
block
The default value for font-display
is block
. With block
, the browserblocks the rendering of any text that uses the specified web font. Differentbrowsers behave slightly differently. Chromium and Firefox block rendering forup to a maximum of 3 seconds before using a fallback. Safari blocks indefinitelyuntil the web font has loaded.
swap
swap
is the most widely used font-display
value. swap
does not blockrendering, and shows the text immediately in a fallback before swapping in thespecified web font. This lets you show your content immediately without waitingfor the web font to download.
However, the downside of swap
is that it causes a layout shift if the fallbackweb font and the web font specified in your CSS varies greatly in terms of lineheight, kerning, and other font metrics. This can affect your website's CLS ifyou don't take care to use preload
hint to load a web font resource as soon aspossible, or if you don't consider other font-display
values.
fallback
The fallback
value for font-display
is something of a compromise betweenblock
and swap
. Unlike swap
, the browser blocks rendering of a font, butswap in fallback text only for a very short period of time. Unlike block
,however, the blocking period is extremely short.
Using the fallback
value can work well on fast networks where, if the web fontdownloads quickly, the web font is the typeface used immediately on the page'sinitial rendering. However, if networks are slow, the fallback text is seenfirst after the blocking period elapses, and then swapped out when the web fontarrives.
optional
optional
is the most stringent font-display
value, and only uses the webfont resource if it downloads within 100 milliseconds. If a web font takeslonger than that to load, it isn't used on the page, and the browser uses thefallback typeface for the current navigation while the web font is downloaded inthe background and placed in the browser cache.
As a result, subsequent page navigations can use the web font immediately, sinceit's already downloaded. font-display: optional
avoids the layout shift seenwith swap
, but some users don't see the web font if it arrives too late on theinitial page navigation.
Font demos
Test your knowledge
When does the browser download a web font resource (assuming it isn't fetched with a preload
directive)?
As soon as the reference to it is discovered in a style sheet.
Try again.
When the page's CSSOM is built and it is determined the web font is needed for the current layout.
Correct!
What is the only (and most efficient) format necessary to serve web fonts to all modern browsers?
WOFF2
Correct!
WOFF
Try again.
TTF
Try again.
EOT
Try again.
Up next: Code-split JavaScript
With an understanding of font optimization under your belt, you can now moveonto the next module, which covers a topic that has a high potential to improveinitial page load speed for your users, and that is to defer the loading ofJavaScript through code splitting. By doing so, you can keep bandwidth and CPUcontention as low as possible during the startup phase of a page, a period oftime in which users are quite likely to interact with it.