How can web fonts impact website performance?
Fonts are one of the vital resources in a website as they make the content visible and readable to users, so it is of high priority to load fonts in a way that the texts become visible to the users as soon as possible. In this article, we will discuss the impact of web fonts on website performance and how we can optimize them to provide better and faster performance.
In this article, you will read about:
Fonts’ effects on the web page performance
Web fonts can impact a web page’s performance by delaying the visibility of texts at the time of page loading. This can affect the performance in two ways:
1. Delayed text rendering
When a web font(s) has not loaded, it can cause a delay in text rendering. This delay mostly impacts the First Contentful Paint (FCP) and sometimes the Largest Contentful Paint (LCP) which are two Core Web Vitals (CWV) metrics.
2. Layout shifts
By delaying in main web font loading, the font swapping needs to happen, but font swapping can also shift layout and impact Cumulative Layout Shift (CLS) which is another Core Web Vitals metric. This layout shift happens when the main font and its fallback need different spaces from each other.
How to check if font loading is delayed or not?
Main content font(s) as the important resources on a page, need to be requested and loaded as soon as possible. The sooner fonts are loaded, the faster the page content with the desired font will be displayed. To check if the web font is requested at the right time, you can follow the steps below:
- Open DevTools on Google Chrome browser by pressing Control+Shift+C or F12 on Windows and Chrome OS, or Command+Option+C on macOS.
- Head over to the Network tab.
- Select Font.
- Refresh the page.
- By page loading, click on a font, and then from the Timing tab, you can see “Started time” as the start time for a web font request.
How to display text immediately when a page is loaded?
To prevent or overcome the negative impacts of delayed font loading, there are some ways with which you can anticipate the texts becoming immediately available to read after a page is loaded. These methods are divided into three main phases: Font loading, font delivering, and font rendering.
1. Font loading
In this first phase, you will see the methods for loading fonts sooner, as they are critical for page content to become visible as soon as possible.
1.1. Adding fonts inline
Inline font declaration is a practical way for some websites with which it is possible to define font paths and other vital resources in the <head> of the website. This method is advanced and may not be implemented on every website as it needs other extra processes and considerations.
It is important to consider that by inlining fonts, if other parts of CSS are not inlined as well, the browser should wait until the CSS is fully loaded before checking if the fonts are needed.
It is recommended not to inline all fonts, especially the larger ones, as they cause delays in main content delivery and also finding other resources.
<head>
<style>
@font-face {
font-family: "Open Sans";
src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}
body {
font-family: "Open Sans";
}
</style>
</head>
1.2. Preconnect to fonts cross-origin resources
If a website uses fonts from third-party origins, it is highly recommended to preconnect the cross-origin resource where fonts are served using preconnect resource hint. To preconnect to third-party origins, you can add the “preconnect” attribute to the that is located in the <head>. It is necessary to use the “crossorigin” attribute, because fonts must be sent over the cross-origin resource sharing (CORS) mechanism.
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
</head>
1.3. Preload fonts
Preloading fonts is another effective way to load fonts during the page loading with a high priority. Preloading fonts can be an effective way as the browsers will not wait too long to understand if the font is needed or not. So, they take the necessary actions to download and load fonts as soon as possible. To preload fonts, the “preload” attribute should be used in the <link>, and crossorigin attribute, which indicates the CORS connection, should be added the same as preconnect.
<link rel="preload" href="/font.woff2" as="font" type="font/woff2" crossorigin>
You can find detailed information about preload and preconnect resource hints in the “How resource hints can help website performance?” article.
2. Font delivery
The faster the fonts are delivered, the faster the texts become visible to the users. It is important to deliver the downloaded fonts in the previous phase in the right and fast way.
2.1. Self-hosted fonts
Self-hosted fonts can be delivered faster as they do not require a third-party connection. But for using this method, you need to make sure that you are using a Content Delivery Network (CDN) and HTTP/2 technologies.
2.2. Using WOFF2
Modern fonts such as WOFF2 or WOFF, which are supported by all well-known modern browsers, are highly recommended to be used as they provide higher compression in comparison to the older formats like TTF and less data download for users, so it can lead to a faster web page performance. WOFF2 is even more optimized and can compress 30% more than WOFF, for this reason, it is best to only use WOFF2 to prevent any incorrect or double font downloads and have a simple CSS and lighter workflow. If you think of old browsers that do not support WOFF2, you can have fallback fonts. Therefore, users with old browsers can easily see your website content with fallback fonts.
2.3. Using subset fonts
Font files usually contain different glyphs for all the characters and some of them may not be used on pages. A good way to reduce font file sizes is to subset fonts. For this aim, there is a descriptor unicode-range located in @font-face which declares characters for which a font is to be used.
@font-face {
font-family: 'Roboto';
src: url('https://fonts.googleapis.com/css2?family=Roboto:wght@400&display=swap') format('woff2');
unicode-range: U+0020-007F; /* Basic Latin */
}
By using unicode-range, fonts that contain one or more of the characters defined in the unicode-range will be downloaded on a page. unicode-range is usually used to serve font files based on the website languages based on the subsetting technique (a technique that serves font files in smaller portions of glyphs that are included in the original font files).
Google Fonts provides different font files and subset fonts automatically. This technique is mostly possible for external fonts that you want to use on your website (including Google Fonts), but if you go with self-hosting font files, then you cannot easily use this font optimization feature.
To have subset fonts on a self-hosting method, you need to make changes in font files by generating font subsets and then self-hosting them. Popular tools for generating subset fonts are subfont and glyphanger.
2.4. Using fewer web fonts
Since web fonts need to be downloaded in the initial loading of a web page, it is better not to overuse web fonts, as they may not be immediately available after a user requests page loading. System fonts and variable fonts are two suitable alternatives with which the number of web fonts can be reduced.
System fonts are the fonts that have already been installed on the operating systems and that is why they are good alternatives for web fonts as there is no need to download them. System fonts can vary based on the operating systems and their versions, so it is recommended to use them as fallback fonts, NOT main fonts. By choosing the system fonts, which are common in most operating systems as fallback fonts, most users will be able to see the same fallback font.
Here is a list of system fonts, called web safe fonts, that are available on almost all known operating systems and can be used as fallback fonts:
Font name | Font type |
---|---|
Arial | sans-serif |
Courier New | monospace |
Georgia | serif |
Times New Roman | serif |
Trebuchet MS | sans-serif |
Verdana | sans-serif |
font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif
A variable font has a default style value, and to manipulate it, you can add different axes to it. For example, it was necessary to have different fonts for font weights like light, regular, semi-bold in the traditional fonts, and bold, but now by using variable fonts, “weight” axes can be defined for the font containing all those font weight styles.
Variable fonts are not always an optimized option for all websites as their file sizes are larger than normal (non-variable) fonts due to containing more styles. So, variable fonts are always recommended for websites that should use different styles and weights of fonts.
3. Font rendering
The last and most important phase is font rendering. When a web font is not loaded yet, the browser should decide if to wait for the font to be finally loaded or load the content by using the fallback font(s). This browser behavior is defined by using the font-display attribute in @font-face.
@font-face {
font-family: Roboto, Sans-Serif
src: url(/fonts/roboto.woff) format('woff'),
font-display: swap;
}
font-display Value | Block period | Swap period |
---|---|---|
Auto | Varies by browser | Varies by browser |
Block | 2-3 seconds | Infinite |
Swap | 0ms | Infinite |
Fallback | 100ms | 3 seconds |
As shown in the table above, the font-display attribute has five values: auto, block, swap, fallback, and optional.
Block period: It is the start of the time when the browser requests for the web font. At the end of this period, if the web font is not still available, the page content will be rendered with a fallback font.
Swap period: The swap period comes after the block period, and during this time if the main web font becomes available, it will be replaced with the fallback font without noticeable change during font swapping.
The decision about the right font-display value completely depends on the websites and their functionality, so it is not possible to deliver a fixed font-display strategy for all. However, there are three most applicable font-display values which can be used by most of the websites:
- Optional: By selecting font-display: optional; browsers behave differently. For example, Google Chrome will wait for 100ms, and the main web font should be loaded during this period. Otherwise, after finishing the 100ms period, the web font won’t be used. The positive point about this value is that there is no layout shift related to the font swapping.
- Swap: By selecting font-display: swap; showing a text and also displaying the web font are on the top priorities. However, you need to make sure about delivering the web font as quickly as possible to prevent any layout shifts that are caused by the late web font arrival.
- Block: By selecting By selecting font-display: block; showing a web font is of the top priority, so it is crucial to check if the web font is delivered fast to prevent text display delay and possible layout shifts which are caused because of delaying in web font loading and using fallback font instead. Fallback fonts may occupy the space differently from the main web font, so that is why delaying web font loading can cause layout shifts.
Conclusion
Web fonts, besides their advantages, could have negative impacts on website performance as they can cause issues like delays in the immediate text display or layout shifts. However, by considering their possible negative effects and trying to eliminate them with many ready-to-use solutions, we can benefit from a fast modern website along with web fonts.