Font Loading — стратегии
Font Loading — управление загрузкой веб-шрифтов для предотвращения FOIT (Flash of Invisible Text) и FOUT (Flash of Unstyled Text), минимизации CLS и ускорения LCP через правильный выбор font-display и preloading.
Зачем нужно
Веб-шрифты — распространённый источник задержки: браузер не рендерит текст, пока не загрузит шрифт (FOIT), или рендерит со сдвигом при замене системного шрифта (FOUT → CLS). Неправильная загрузка шрифтов ухудшает LCP и CLS одновременно.
Где используется
- Любой сайт с кастомными веб-шрифтами (Google Fonts, Adobe Fonts, self-hosted)
- Медиа-ресурсы и блоги с большим объёмом текста
- Брендированные приложения с фирменной типографикой
Основной контент
font-display стратегии
@font-face {
font-family: 'MyFont';
src: url('/fonts/myfont.woff2') format('woff2');
font-display: swap; /* Наиболее распространённый выбор */
}
/* font-display значения:
auto — браузер решает (обычно block, до 3s)
block — скрыть текст, ждать шрифт (FOIT, плохо для CLS)
swap — показать fallback, заменить когда готов (FOUT)
fallback — короткий block (100ms), потом swap или отказ
optional — 100ms block, потом только из кеша
*/
Preload критических шрифтов
<head>
<!-- Preload только для шрифтов "above the fold" -->
<link
rel="preload"
href="/fonts/myfont-regular.woff2"
as="font"
type="font/woff2"
crossorigin
>
<!-- crossorigin обязателен даже для same-origin шрифтов! -->
</head>
size-adjust для минимизации CLS при FOUT
/* Подбираем size-adjust чтобы системный шрифт совпадал по размеру */
@font-face {
font-family: 'MyFont';
src: url('/fonts/myfont.woff2') format('woff2');
font-display: swap;
}
/* Fallback с корректировкой размера */
@font-face {
font-family: 'MyFont Fallback';
src: local('Arial');
size-adjust: 93%; /* Масштабирование под целевой шрифт */
ascent-override: 90%; /* Высота символов */
descent-override: 20%; /* Отступ снизу */
line-gap-override: normal;
font-display: swap;
}
body {
font-family: 'MyFont', 'MyFont Fallback', Arial, sans-serif;
}
Self-hosted Google Fonts (оптимально)
# Скачать через google-webfonts-helper
# https://gwfh.mranftl.com/fonts
# Или через fontsource (npm)
npm install @fontsource/inter
// В Next.js (next/font — автоматическая оптимизация)
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin', 'cyrillic'],
display: 'swap',
variable: '--font-inter',
});
Subsetting — только нужные символы
# pyftsubset — создать subset с только нужными символами
pip install fonttools
pyftsubset myfont.ttf \
--unicodes="U+0020-007E,U+0400-04FF" \ # ASCII + Кириллица
--flavor=woff2 \
--output-file=myfont-subset.woff2
Частые ошибки
font-display: block— скрывает текст на время загрузки, ухудшает LCP- Preload всех вариантов шрифта (bold, italic) — загрузка того, что не используется
- Отсутствие
crossoriginна<link rel="preload">для шрифтов — шрифт загружается дважды - Google Fonts через
<link>без preconnect — дополнительный DNS lookup задерживает загрузку
Связанные темы
- _MOC Производительность
- Core Web Vitals -- LCP, FID, CLS
- Критический CSS -- inline critical CSS
- Как браузер рендерит страницу