Оптимізація шрифтів: font-display, preload, subset
Кастомні шрифти — розповсюджена причина повільного FCP та CLS. Браузер повинен завантажити шрифт до відображення тексту (або показати невидимий текст / системний шрифт). Правильна налаштування усуває обидва симптоми.
font-display — управління рендерингом
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap; /* показати fallback миттєво */
}
| Значення | Поведінка | Коли використовувати |
|---|---|---|
auto |
Залежить від браузера | Не використовуйте |
block |
Сховати текст до завантаження (FOIT) | Іконочні шрифти |
swap |
Fallback → основний при завантаженні | Основний текст |
fallback |
100мс сховано, потім swap | Баланс FCP/CLS |
optional |
Тільки якщо вже закеширований | Некритичні шрифти |
Для основного тексту — swap. Для декоративних заголовків де FOUT допустим — swap. Для іконочних шрифтів — block (інакше іконки відобразяться як символи).
Preload критичного шрифту
<head>
<!-- Preload до завантаження CSS -->
<link rel="preload"
href="/fonts/inter-regular.woff2"
as="font"
type="font/woff2"
crossorigin>
<!-- Якщо кілька граничних — preload тільки використовувані above-the-fold -->
<link rel="preload" href="/fonts/inter-700.woff2" as="font" type="font/woff2" crossorigin>
</head>
Preload тільки шрифти першого екрана. Preload усіх граничних уповільнює завантаження.
Subset — тільки потрібні символи
Повний Inter містить латиницю, кириллицю, грецький, іврит — ~500 кБ. Підмножина тільки з потрібними символами — 30–80 кБ.
/* unicode-range для кириллиці */
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-cyrillic.woff2') format('woff2');
font-weight: 400;
font-display: swap;
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* Латиниця — окремий файл */
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-latin.woff2') format('woff2');
font-weight: 400;
font-display: swap;
unicode-range: U+0000-00FF, U+0131, U+0152-0153;
}
Браузер завантажує тільки файли з символами, що зустрічаються на сторінці.
Генерація subset через pyftsubset
# Установка
pip install fonttools brotli
# Створення subset із кириллицею + базовою латиницею
pyftsubset inter-regular.ttf \
--unicodes="U+0020-007E,U+00A0-00FF,U+0400-045F,U+0490-0491" \
--layout-features="kern,liga,calt" \
--flavor=woff2 \
--output-file=inter-regular-subset.woff2
Self-hosted vs Google Fonts
Google Fonts вводить DNS lookup + connection overhead для кожного нового користувача. Self-hosted шрифти:
- Видаляють cross-origin затримку
- Дозволяють використовувати HTTP/2 push або preload
- Працюють без залежності від сторонньої CDN
# Скачайте шрифт з правильним subset
# Використовуючи google-webfonts-helper (gwfh.mranftl.com)
# або fontsource npm пакет
npm install @fontsource-variable/inter
/* Fontsource — автоматично включає потрібні файли */
@import '@fontsource-variable/inter/cyrillic.css';
@import '@fontsource-variable/inter/latin.css';
Компенсація CLS від font-swap
/* Підберіть метрики для fallback шрифту */
@font-face {
font-family: 'InterFallback';
src: local('Arial');
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
size-adjust: 107%;
}
body {
font-family: 'Inter', 'InterFallback', sans-serif;
}
Інструменти для підбору значень: fontaine npm-пакет або next/font (автоматично для Next.js).
Variable fonts
Один файл замість окремих для кожного граничного:
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-variable.woff2') format('woff2-variations');
font-weight: 100 900; /* діапазон */
font-display: swap;
}
/* Використання */
h1 { font-weight: 700; }
body { font-weight: 400; }
.light { font-weight: 300; }
Variable font Inter (~170 кБ subset кириллиця+латиниця) vs. окремі файли для 400 + 700 (~120 кБ). Вигідно при ≥ 3 граничних.
Час оптимізації: 4–8 годин: скачайте шрифти, зробіть subset, налаштуйте preload та CSS.







