Оптимизация шрифтов на сайте: системные шрифты, font-display, предзагрузка и FOIT
1. Почему шрифты блокируют отображение текста
Пока браузер не получил файл шрифта, он не знает, как должен выглядеть текст, и по умолчанию делает его невидимым (FOIT, Flash of Invisible Text). В старых браузерах это скрытие длится 3 секунды, в новых — 1 секунду, после чего принудительно показывается fallback-шрифт. Проблема в том, что текст первого экрана и есть элемент LCP: если он ждёт шрифт, загрузка шрифта затягивает LCP.
Типичная ошибка на сайте: автор темы ради «дизайна» подключает все начертания Inter или Roboto из Google Fonts (от 100 до 900, всего 9 начертаний), каждое по 100 КБ — 900 КБ за одну загрузку. На 3G только шрифты качаются 3–5 секунд, а пользователь видит пустой экран. Метрики Core Web Vitals, связанные со шрифтами, смотрите в Оптимизация Core Web Vitals, а как настроить CDN — в Глобальное ускорение CDN.
| Вопрос | Влияние на производительность | Типичный объём |
|---|---|---|
| Загрузка всех начертаний (9 штук) | Плюс 800 КБ на первом экране | 80–120 КБ на начертание |
| Китайский шрифт без сабсета | 2–8 МБ в одном файле | Намного больше бюджета первого экрана |
| font-display по умолчанию block | FOIT скрывает текст на 1–3 секунды | Текст не виден |
| Ключевой шрифт не предзагружен | Шрифт обнаруживается поздно, задержка 200 мс | LCP замедляется |
| Больше трёх семейств | Каждое семейство нужно скачать | В сумме 300–500 КБ |
2. Системный стек шрифтов: ответ по умолчанию для B2B-сайта
Системный стек шрифтов (system font stack) использует шрифты, уже установленные на устройстве пользователя: ноль сетевых запросов, мгновенное отображение. Контент B2B-сайта — это в основном таблицы характеристик, описания кейсов и технические статьи; для такой вёрстки не нужны декоративные или брендовые шрифты, системного стека вполне достаточно визуально, и он одинаково выглядит на всех платформах.
Готовый CSS-стек: font-family: -apple-system, BlinkMacSystemFont, “Segoe UI”, Roboto, “Helvetica Neue”, Arial, “PingFang SC”, “Microsoft YaHei”, sans-serif. Он покрывает macOS, Windows, Android и iOS — для латиницы и китайского есть свои системные шрифты. Контринтуитивный вывод:системные шрифты не делают сайт «непрофессиональным», наоборот — GitHub, Stripe и Linear, эти эталоны дизайна, используют системный стек шрифтов. Как выбрать тему WP — см.Технологический стек WordPress.
| Подход | Текст первого экрана | Дополнительная загрузка | Тип сайта |
|---|---|---|---|
| Только системные шрифты | Показывается сразу | 0KB | Большинство B2B-сайтов |
| 1 веб-шрифт для заголовков | Замена после fallback | от 30 до 80KB | Сайты с акцентом на бренд |
| 2 семейства веб-шрифтов | Замена после fallback | 80–150 КБ | Брендовые сайты с дизайном во главе |
| 3+ веб-шрифта | Заметный FOUT/FOIT | >200KB | Не рекомендуется |
| Полный китайский веб-шрифт | FOIT на несколько секунд | 2–8MB | Практически неприменимо |
3. font-display:swap и FOIT: не прячьте текст
font-display — свойство внутри @font-face, оно управляет тем, как показывается текст, пока шрифт загружается. Четыре значения: auto (по умолчанию в браузере, раньше это был block), block (текст ненадолго скрывается на 3 секунды, затем fallback), swap (сразу показывается fallback, а когда шрифт загрузится — заменяется), optional (браузер решает сам и склоняется к тому, чтобы не загружать шрифт).
Для B2B-сайтов всегда используйте swap. На 3G-сети block означает пустой первый экран на 3 секунды — посетитель уже уйдёт; optional подходит для шрифтов, не критичных для бренда, но он непредсказуем. Частое заблуждение — «swap вызывает мерцание шрифта (FOUT)», но для B2B-сайта важнее, чтобы пользователь сразу прочитал характеристики и контакты, чем ждал декоративный заголовок. Мерцание шрифта вполне допустимо, а вот невидимый текст — реальная потеря. О стратегии загрузки CSS/JS — см.Оптимизация CSS/JS.
| font-display | Период блокировки | После загрузки шрифта | Когда подходит |
|---|---|---|---|
| auto/block | Текст невидим до 3 секунд | Замена на веб-шрифт | Не рекомендуется |
| swap | Сразу показывается fallback | Замена, когда шрифт загружен | По умолчанию для B2B-сайтов |
| fallback | Скрытие на 100ms, затем fallback | Замена, только если загрузился за 3 секунды | Полукритичные шрифты |
| optional | Скрытие на 100ms, затем fallback | В этот визит замены не будет | Чисто декоративные шрифты |
4. preload и сабсеттинг: ускоряем то, что должно быть быстрым
Если заголовок первого экрана обязательно должен быть веб-шрифтом, используйте preload, чтобы браузер скачал его заранее с высоким приоритетом: добавьте в head <link rel=”preload” href=”font.woff2″ as=”font” type=”font/woff2″ crossorigin>. Тогда шрифт начнёт загружаться ещё до разбора CSS, и LCP выиграет 200–400 миллисекунд. Учтите: атрибут crossorigin опускать нельзя, иначе preload не сработает.
Субсеттинг (subset) — ещё одна обязательная оптимизация. Для английских шрифтов оставляем только латиницу, цифры и частые символы — размер падает со 100 КБ до 30 КБ. Для китайских шрифтов набор символов настолько велик, что даже после субсеттинга остаётся от 200 КБ до 1 МБ, поэтому для китайских сайтов и советуют сразу системные шрифты. С помощью glyphhanger или параметра text в Google Fonts загружайте только используемые символы. Конкретный пример: в заголовке первого экрана всего 20 иероглифов — субсеттим только их, и файл сжимается с 4 МБ до 5 КБ. Кэширование в CDN — см.Сравнение вариантов CDN.
| Действие по оптимизации шрифтов | Выигрыш по размеру и задержке | Сложность внедрения | Рекомендация |
|---|---|---|---|
| Только формат woff2 | На 30% меньше, чем ttf | Низкая | Обязательно |
| Загружать только начертания 400 и 700 | Скачивание меньше на 60% | Низкая | Обязательно |
| Субсеттинг английского набора символов | Ещё минус 50% | Средний | Рекомендуется |
| preload шрифта первого экрана | LCP раньше на 200–400 мс | Низкая | Для заголовка первого экрана использовать |
| Полный китайский веб-шрифт | Минус | Высокий | Не делать |
Пять. Приёмка: смотрим водопад загрузки шрифтов в DevTools
Как проверить, что оптимизация шрифтов сделана? Откройте панель Network в Chrome DevTools, отфильтруйте Font и посмотрите на три вещи: количество файлов шрифтов (должно быть ≤2 семейства, ≤2 начертания на семейство), размер файлов шрифтов (здоровый показатель — ≤50 КБ на файл) и момент начала скачивания (после preload они должны быть среди самых первых запросов, а не обнаруживаться после разбора CSS). Если какой-то файл шрифта больше 100 КБ, стоит вернуться и проверить, не ошибка ли это в начертаниях или субсеттинге.
Затем в Lighthouse посмотрите два аудита: «Avoid layout shifts from web fonts» и «Preload key requests». Вот выполнимый чек-лист: у всех font-display стоит swap, шрифт первого экрана в preload, формат woff2, нет старых форматов ttf/eot, в Google Fonts используется параметр display=swap. Как работать со шрифтами на многоязычных сайтах — см.Работа с графиками на многоязычном сайте. Мониторинг сайта — см.Оповещения мониторинга сайта.
| Пункт приёмки | Критерий нормы | Инструмент измерения |
|---|---|---|
| font-display | Везде swap или fallback | Проверка CSS |
| preload шрифта первого экрана | Шрифт заголовка первого экрана в preload | DevTools Network |
| Формат файлов шрифтов | Только woff2 | Фильтр Font в Network |
| Размер одного шрифта | ≤50 КБ | Столбец Size в Network |
| Количество семейств шрифтов | ≤2 | Проверка CSS |
| 75-й процентиль LCP | ≤2,5 секунды | CrUX/RUM |
FAQ: частые вопросы
Обязательно ли использовать веб-шрифты на отдельном B2B-сайте?
Чем font-display:swap отличается от block?
Можно ли использовать веб-шрифты для китайского?
Зачем добавлять crossorigin при preload шрифта?
Как загрузить Google Fonts быстрее всего?
Как принять работу после оптимизации шрифтов?
Шесть. FOUT и сдвиг макета: как избежать прыжков при смене шрифта
При стратегии swap подмена fallback-шрифта на веб-шрифт может сдвинуть страницу: ширина и высота знаков различаются — отсюда и берётся CLS (совокупный сдвиг макета). Stripe измеряла это: одна подмена шрифта даёт в среднем 0,05–0,1 CLS, то есть ровно на границе нормы 0,1. На B2B-сайтах текст длинный, абзацев много, и из-за разницы в переносах строк картинки прыгают вверх-вниз.
Решают два дескриптора: font-size-adjust и size-adjust. В @font-face задайте size-adjust: 105% и ascent-override, чтобы метрики веб-шрифта были близки к fallback, — тогда при подмене почти ничего не прыгает. Ещё проще подобрать пару, где метрики fallback и веб-шрифта близки: например, для Inter взять fallback Arial или вообще не менять системный стек шрифтов. Конкретная проверка: в Lighthouse посмотрите аудит «Избегайте сдвигов макета при использовании веб-шрифтов». Если оценка низкая, сначала выясните, не из-за swap ли это, и только потом решайте, добавлять ли size-adjust.
| Как работать с FOUT | Улучшение CLS | Сложность внедрения |
|---|---|---|
| Не трогать, смириться с мерцанием | от 0,05 до 0,1 | Нет |
| Тонкая настройка метрик через size-adjust | Снизить до 0,02 и ниже | Средний, нужно тестировать |
| Выбрать fallback с близкими метриками | Снизить до 0,03 и ниже | Низкая |
| Просто отказаться от Web-шрифтов | 0 | Ноль затрат |
В заключение
Главный принцип оптимизации шрифтов прост: пользователи B2B-сайта приходят читать характеристики, смотреть кейсы и искать контакты, а не любоваться типографикой. Системный стек шрифтов — правильный ответ в 95% случаев: сэкономленные сотни килобайт и сотни миллисекунд важнее визуальной разницы. Даже если оставляете Web-шрифты, держитесь четырёх рамок: два семейства, два начертания, формат woff2, загрузка swap.
Три шага на практике. Первый: на этой неделе переведите шрифты темы на системный стек и удалите лишние подключения Google Fonts. Второй: всем оставленным Web-шрифтам добавьте font-display:swap, оставьте только начертания 400 и 700, разместите файлы woff2 на своём сервере. Третий: для шрифта заголовка первого экрана добавьте preload и пропишите crossorigin. Через две недели проверьте, улучшились ли LCP и аудиты, связанные со шрифтами.
Фраза, которую стоит запомнить: пользователь не задержится на секунду дольше из-за того, что на вашем сайте стоит Inter, но закроет вкладку, если будет три секунды ждать загрузки шрифта. Шрифт — это деталь, но именно от деталей зависит, удержите ли вы внимание в те самые 2,5 секунды первого экрана.
