A designer delivers a mockup with a corporate font, a developer connects Google Fonts — and the page suddenly drops in LCP. This is not rare: fonts from Google Fonts are used on approximately 43% of websites on the internet, and on mobile devices they reduce the share of 'good' LCP metrics from 72,3% to 63,0% — almost by 9,3 points. The overall pass rate of Core Web Vitals drops from 43,9% to 40,3%. The numbers are small in absolute terms, but on the scale of traffic they turn into real losses in conversion and search rankings.
The problem is exacerbated by how browsers behave during font loading. Chromium and Firefox block text rendering for up to 3 seconds, then show a fallback. Safari, however, can wait indefinitely if behavior is not explicitly set via font-display. That is, without configuration, the same website in Safari may show a blank screen longer than in Chrome — this is a purely technical detail that often falls out of design briefs.
Many confuse font-family: system-ui with a classic stack like the one used by GitHub and Medium: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif. The difference is fundamental.
| Parameter | system-ui | Explicit stack (GitHub/Medium) |
|---|---|---|
| Compatibility with older browsers | Worse — not supported in older versions of Edge and some Android WebView | Better — covers more environments with explicit names |
| Predictability of font rendering | Returns the system UI font, which may differ from the OS's regular text font | Allows explicitly specifying the desired font for each platform |
| Code volume | One keyword | Long string, requires support and updates |
| When to use | Rapid prototypes, internal tools | Production interfaces, where stability across all OSes is important |
In practice, for production, it's better to use an explicit list: it's more predictable and doesn't come with surprises when Google changes behavior once again system-ui in Chrome.
The mistake of most hybrid solutions is that they are described abstractly — 'headings in web font, text in system font' — without tying it to the product type. In practice, the boundary varies depending on the interface.
| Interface type | Web font (brand) | System font |
|---|---|---|
| SaaS dashboard | Logo, product name in the header | All buttons, tables, forms, navigation, notification texts |
| Marketing website / landing | H1, H2, highlights, quotes, large numbers in benefit blocks | Main text, footer, legal blocks |
| E-commerce | Brand name, category headings, large promo banners | Price, 'Buy' button, product specifications, filters |
The logic is simple: elements affecting LCP (usually the first screen with text of cards, prices, or main content) are almost always better left in system font. Page headings rarely are LCP elements — so using web font on them does not penalize the metric. With such a setup, one WOFF2 file weighing 30–50 KB is sufficient for the page instead of a full family in 150–240 KB. WOFF2 also compresses data 30% better than WOFF format thanks to Brotli algorithm — if you're still using the old format, this is the first thing to change.
The choice of value depends not on 'taste', but on the page type and what is more critical — visual stability or absence of visual flicker.
Practical rule: headings on a marketing website — swap, UI elements in the product, if you've nevertheless decided to use a web font there — optional.
Even without web fonts, shifts are possible — SF Pro on macOS, Segoe UI on Windows, and Roboto on Android have different line heights, and in single-line elements such as buttons or badges, this results in a spread of 1-2 pixels between platforms. Adding a web font increases the spread, because the metrics of the brand font and the fallback font almost never perfectly match.
This is not solved by abandoning the web font, but by precise tuning of CSS descriptors inside @font-face:
size-adjust, to scale the fallback font to the brand font's size — this removes the difference in text width occupied.ascent-override, descent-override and line-gap-override, to align the line height of the fallback font with the actual metrics of the brand font.This setting takes an hour of frontend work, but removes the visual 'jump' almost completely — without abandoning the brand font and without worsening LCP.
The first and most expensive mistake is to load the entire font family 'for the future': regular, italic, bold, extrabold at 30-50 KB each, although only two variants are actually used. This adds hundreds of kilobytes with no visible benefit.
The second mistake is to set font-display: block by default, because 'it's safer for the brand.' In practice, this is the worst option for Safari, where the lock becomes almost infinite without an explicit timeout.
Third — to use a web font for text in product cards or data tables. Such text usually coincides with the LCP element, and it is precisely here that performance hits sales the hardest.
The final recommendation for SaaS and most digital products: system — for all UI (buttons, forms, navigation, tables), one brand font — for the logo and large headings. Such a combination minimizes both CLS and LCP simultaneously, leaving the brand exactly the visual presence that actually works on recognizability.
A designer delivers a mockup with a corporate font, a developer connects Google Fonts — and the page suddenly drops in LCP. This is not rare: fonts from Google Fonts are used on approximately 43% of websites on the internet, and on mobile devices they reduce the share of 'good' LCP metrics from 72,3% to 63,0% — almost by 9,3 points. The overall pass rate of Core Web Vitals drops from 43,9% to 40,3%. The numbers are small in absolute terms, but on the scale of traffic they turn into real losses in conversion and search rankings.
The problem is exacerbated by how browsers behave during font loading. Chromium and Firefox block text rendering for up to 3 seconds, then show a fallback. Safari, however, can wait indefinitely if behavior is not explicitly set via font-display. That is, without configuration, the same website in Safari may show a blank screen longer than in Chrome — this is a purely technical detail that often falls out of design briefs.
Many confuse font-family: system-ui with a classic stack like the one used by GitHub and Medium: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif. The difference is fundamental.
| Parameter | system-ui | Explicit stack (GitHub/Medium) |
|---|---|---|
| Compatibility with older browsers | Worse — not supported in older versions of Edge and some Android WebView | Better — covers more environments with explicit names |
| Predictability of font rendering | Returns the system UI font, which may differ from the OS's regular text font | Allows explicitly specifying the desired font for each platform |
| Code volume | One keyword | Long string, requires support and updates |
| When to use | Rapid prototypes, internal tools | Production interfaces, where stability across all OSes is important |
In practice, for production, it's better to use an explicit list: it's more predictable and doesn't come with surprises when Google changes behavior once again system-ui in Chrome.
The mistake of most hybrid solutions is that they are described abstractly — 'headings in web font, text in system font' — without tying it to the product type. In practice, the boundary varies depending on the interface.
| Interface type | Web font (brand) | System font |
|---|---|---|
| SaaS dashboard | Logo, product name in the header | All buttons, tables, forms, navigation, notification texts |
| Marketing website / landing | H1, H2, highlights, quotes, large numbers in benefit blocks | Main text, footer, legal blocks |
| E-commerce | Brand name, category headings, large promo banners | Price, 'Buy' button, product specifications, filters |
The logic is simple: elements affecting LCP (usually the first screen with text of cards, prices, or main content) are almost always better left in system font. Page headings rarely are LCP elements — so using web font on them does not penalize the metric. With such a setup, one WOFF2 file weighing 30–50 KB is sufficient for the page instead of a full family in 150–240 KB. WOFF2 also compresses data 30% better than WOFF format thanks to Brotli algorithm — if you're still using the old format, this is the first thing to change.
The choice of value depends not on 'taste', but on the page type and what is more critical — visual stability or absence of visual flicker.
Practical rule: headings on a marketing website — swap, UI elements in the product, if you've nevertheless decided to use a web font there — optional.
Even without web fonts, shifts are possible — SF Pro on macOS, Segoe UI on Windows, and Roboto on Android have different line heights, and in single-line elements such as buttons or badges, this results in a spread of 1-2 pixels between platforms. Adding a web font increases the spread, because the metrics of the brand font and the fallback font almost never perfectly match.
This is not solved by abandoning the web font, but by precise tuning of CSS descriptors inside @font-face:
size-adjust, to scale the fallback font to the brand font's size — this removes the difference in text width occupied.ascent-override, descent-override and line-gap-override, to align the line height of the fallback font with the actual metrics of the brand font.This setting takes an hour of frontend work, but removes the visual 'jump' almost completely — without abandoning the brand font and without worsening LCP.
The first and most expensive mistake is to load the entire font family 'for the future': regular, italic, bold, extrabold at 30-50 KB each, although only two variants are actually used. This adds hundreds of kilobytes with no visible benefit.
The second mistake is to set font-display: block by default, because 'it's safer for the brand.' In practice, this is the worst option for Safari, where the lock becomes almost infinite without an explicit timeout.
Third — to use a web font for text in product cards or data tables. Such text usually coincides with the LCP element, and it is precisely here that performance hits sales the hardest.
The final recommendation for SaaS and most digital products: system — for all UI (buttons, forms, navigation, tables), one brand font — for the logo and large headings. Such a combination minimizes both CLS and LCP simultaneously, leaving the brand exactly the visual presence that actually works on recognizability.