Шрифты: preload, font-display
Почему важно
Проблемы:
- FOIT — текст невидим.
- FOUT — текст мигает.
- CLS — сдвиг при подгрузке.
- LCP — шрифт влияет.
Что даёт оптимизация:
- Быстрый рендер.
- Нет сдвига.
- Лучше UX.
- Лучше CWV.
Правило: шрифты — обязательный пункт CWV.
Форматы
WOFF2:
- Современный.
- Brotli-сжатие.
- Поддержка 95%+.
WOFF:
- Старый fallback.
- Без WOFF2.
TTF / OTF:
- Не для веба.
EOT / SVG:
- Устарели.
Правило: только WOFF2.
@font-face
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-var.woff2') format('woff2-variations');
font-weight: 100 900;
font-display: swap;
font-style: normal;
}
Что важно:
format('woff2-variations')— variable font.font-weight— диапазон.font-display: swap.
font-display
Что это: как показывать шрифт пока грузится.
Значения:
auto— решение браузера.block— FOIT (3s).swap— сразу fallback.fallback— короткий FOIT.optional— может не загрузиться.
Правило: swap — стандарт.
swap vs optional
swap:
- Сразу fallback.
- Потом подменяет.
- Может быть CLS.
optional:
- Использует fallback если медленно.
- Нет CLS.
- Может не показать кастом.
Правило: swap для LCP-заголовков, optional для остального.
Variable fonts
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-var.woff2') format('woff2-variations');
font-weight: 100 900;
font-style: normal;
font-display: swap;
}
Что даёт:
- Один файл вместо 6 (100–900).
- Меньше загрузки.
- Гибкость весов.
Правило: variable — везде где есть.
Subset
Что это: только нужные символы.
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153;
}
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-cyrillic.woff2') format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1;
}
Что даёт:
- По языку.
- Меньше размер.
- Загружается только нужный.
Правило: subset — обязательно для кириллицы.
Subset для кириллицы
Что включить:
- Latin — базовый.
- Latin-ext — для акцентов.
- Cyrillic — русский.
- Cyrillic-ext — украинский, белорусский.
Что экономит: 50–70% размера.
preload
<link
rel="preload"
href="/fonts/inter-var.woff2"
as="font"
type="font/woff2"
crossorigin
>
Что важно:
as="font"— тип.crossorigin— обязательно для шрифтов.- Только критичные.
Правило: preload — для LCP-шрифта.
Не preload всё
Что плохо:
<link rel="preload" as="font" href="regular.woff2" crossorigin>
<link rel="preload" as="font" href="bold.woff2" crossorigin>
<link rel="preload" as="font" href="italic.woff2" crossorigin>
<link rel="preload" as="font" href="bold-italic.woff2" crossorigin>
Что даёт: конкуренция за bandwidth.
Правило: preload — 1–2 шрифта макс.
Fallback stack
body {
font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
}
Что даёт:
- System font сразу.
- Кастом — когда загрузится.
- Нет FOIT.
Правило: system-ui — первый fallback.
size-adjust
Что делает: подгоняет размер fallback под кастом.
@font-face {
font-family: 'Inter Fallback';
src: local('Arial');
size-adjust: 107%;
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
}
body {
font-family: 'Inter', 'Inter Fallback', sans-serif;
}
Что даёт: минимум CLS между fallback и кастом.
Правило: size-adjust — для метрических fallback.
next/font
Next.js:
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin', 'cyrillic'],
display: 'swap',
variable: '--font-inter',
});
export default function RootLayout({ children }) {
return <html className={inter.variable}>{children}</html>;
}
Что даёт:
- Авто self-host.
- Авто subset.
- Авто preload.
- Zero CLS.
Правило: в Next.js — next/font.
Self-host
Почему:
- Контроль версии.
- Не зависим от Google.
- GDPR.
- Быстрее (свой CDN).
Как:
npx google-fonts-helper download 'Inter' --output ./public/fonts
Правило: self-host — стандарт 2026.
GDPR и Google Fonts
Проблема: Google Fonts = передача IP в Google.
Решение: self-host.
Правило: в ЕС — только self-host.
System font stack
font-family:
system-ui,
-apple-system,
'Segoe UI',
Roboto,
'Helvetica Neue',
Arial,
sans-serif;
Что даёт:
- Ноль загрузки.
- Нативные шрифты.
- Быстро.
Правило: для утилитарных проектов — system-ui.
Что НЕ делать
font-display: block.- 6 weights сразу.
- TTF / OTF в вебе.
- Google Fonts CDN.
- Preload всего.
- Без subset для кириллицы.
Практика
1. Замените TTF на WOFF2.
2. Включите font-display: swap.
3. Subset для кириллицы.
4. Variable font если есть.
5. Preload главного шрифта.
6. size-adjust для fallback.
7. Self-host.
8. next/font в Next.js.
9. Замерьте FOIT / FOUT.
10. Проверьте CLS.
Частые ошибки
1. font-display: block:
FOIT 3s
Решение: swap.
2. Без preload:
Поздняя загрузка
Решение: preload.
3. Preload всего:
Конкуренция
Решение: 1–2.
4. Без subset:
+200 KB
Решение: subset.
5. Google CDN:
GDPR риск
Решение: self-host.
6. TTF:
В 2× больше
Решение: WOFF2.
7. 6 weights:
6 файлов
Решение: variable.
8. Без size-adjust:
CLS
Решение: метрический fallback.
Итог
- WOFF2 — только формат.
font-display: swap— стандарт.- Variable fonts — один файл.
- Subset — обязательно.
- Preload — 1–2 шрифта.
- System fallback — первым.
- size-adjust — против CLS.
- Self-host — GDPR.
next/font— в Next.js.- System-ui — быстрая альтернатива.
Дальше — критический CSS.