Оптимизация шрифтов сайта: preload, subset и стабильный текст
Web-шрифт влияет не только на внешний вид страницы. Пока браузер не обнаружил, не загрузил и не разобрал файл, текст может оставаться невидимым, показываться запасным шрифтом или менять размеры после подстановки основной гарнитуры. Практическая оптимизация шрифтов сайта должна сокращать эту задержку и одновременно сохранять стабильность строк, заголовков и элементов управления.
Почему текст появляется поздно или скачет
Браузер начинает загрузку шрифта только после того, как встретит использующее его CSS-правило и элемент с соответствующим текстом. Если объявление @font-face находится в поздно загружаемом файле стилей, запрос к шрифту тоже начинается поздно. Дополнительную задержку создают редиректы, другой домен, отсутствие постоянного кеширования и слишком крупный файл с ненужными символами.
Дальнейшее поведение задаёт дескриптор font-display. При блокирующем сценарии браузер некоторое время скрывает текст — возникает FOIT, flash of invisible text. При раннем показе системного шрифта текст доступен сразу, но после загрузки web-шрифта возможен FOUT, flash of unstyled text. Если метрики гарнитур различаются, строки переносятся, блок меняет высоту, а соседний контент смещается.
Цель не сводится к безусловной предзагрузке всех файлов. Нужно обеспечить раннюю доставку только критичных начертаний, уменьшить передаваемый набор символов и подобрать запасной шрифт с близкими метриками.
Диагностический алгоритм
1. Зафиксировать фактический набор шрифтов
Откройте страницу в чистом профиле браузера, включите ограничение скорости сети и перезагрузите её с открытой вкладкой Network. Отфильтруйте запросы по типу Font. Для каждого файла запишите URL, формат, размер передачи, момент начала, статус кеша и элемент, который использует начертание.
Во вкладке Computed или Fonts проверьте реально отрисованную гарнитуру. Это помогает обнаружить ситуацию, когда файл загружается, но не применяется из-за неверного font-family, диапазона веса или стиля.
2. Найти источник позднего запроса
Изучите цепочку инициаторов. Нормальная последовательность выглядит коротко: HTML → CSS → font. Если CSS добавляется JavaScript-кодом, импортирует другой CSS или появляется после согласия пользователя, браузер обнаружит шрифт позже. Здесь важно разделять причины: эта статья рассматривает доставку web-шрифтов, а не общую оптимизацию CSS и скорости всей страницы.
3. Наблюдать за подменой текста
Запишите загрузку экрана или используйте покадровый просмотр. Проверьте крупный заголовок, навигацию, кнопки, поля формы и длинные абзацы. Ищите период невидимости, изменение ширины слов, перенос строки, скачок высоты кнопки и смещение контента после завершения запроса к шрифту.
4. Повторить проверку с кешем и без него
Первый визит показывает стоимость загрузки, повторный — корректность кеширования. Тест только на прогретом кеше скрывает проблему новых посетителей, а тест только без кеша не показывает, используется ли долговременное хранение файла.
Рабочая конфигурация @font-face
Для большинства текстовых шрифтов предпочтителен WOFF2. Каждый файл должен иметь точное описание веса и стиля, иначе браузер может синтезировать начертание или загружать неподходящий ресурс.
@font-face {
font-family: "Project Sans";
src: url("/fonts/project-sans-regular-latin-cyrillic.woff2") format("woff2");
font-weight: 400;
font-style: normal;
font-display: swap;
}
swap быстро показывает запасной шрифт и заменяет его после загрузки. Это понятная отправная точка для основного текста, но не гарантия отсутствия смещения. optional разрешает браузеру не выполнять позднюю подмену при неблагоприятных условиях и может быть полезен, когда стабильность важнее обязательного отображения фирменной гарнитуры. block обычно нежелателен для значимого текста, потому что допускает период невидимости.
Preload: только для критичных файлов
Предзагрузка сообщает браузеру о важном шрифте до того, как он будет найден через CSS:
<link rel="preload"
href="/fonts/project-sans-regular-latin-cyrillic.woff2"
as="font"
type="font/woff2"
crossorigin>
Атрибут crossorigin нужен и для шрифтов с того же origin, поскольку запросы шрифтов используют CORS-режим. URL в preload и @font-face должен совпадать буквально: другой путь, параметр версии или редирект способен вызвать два запроса вместо одного.
Предзагружайте только начертания, необходимые в первом экране. Если добавить regular, medium, semibold, bold, italic и набор иконок, они начнут конкурировать за сеть с действительно важными ресурсами. Наличие preload проверяется не по разметке, а по Waterfall: запрос должен стартовать раньше и использоваться соответствующим @font-face.
Subset: уменьшение набора символов
Подмножество содержит только нужные глифы. Для русскоязычного сайта обычно необходимы кириллица, базовая латиница, цифры, знаки пунктуации и используемые специальные символы. Нельзя автоматически брать latin-only: кириллица тогда отобразится системным шрифтом, даже если английские слова используют основную гарнитуру.
Разделение на unicode-диапазоны позволяет браузеру загружать файл только при наличии соответствующих символов:
@font-face {
font-family: "Project Sans";
src: url("/fonts/project-sans-cyrillic.woff2") format("woff2");
font-weight: 400;
font-display: swap;
unicode-range: U+0400-04FF, U+0500-052F;
}
Диапазоны следует строить по реальному контенту и проверять на буквах «ё», украинских или казахских символах, неразрывном пробеле, валютных знаках и типографской пунктуации, если они встречаются на сайте. Чрезмерно узкий subset ломается при обновлении текста, пользовательском вводе или локализации. Лицензия гарнитуры также должна разрешать выбранный способ размещения и модификации файла.
Как уменьшить скачок при смене гарнитуры
Выберите системный fallback, близкий по ширине и высоте строчных знаков. Затем настройте метрики через дескрипторы size-adjust, ascent-override, descent-override и line-gap-override. Значения рассчитывают для конкретной пары шрифтов, а не копируют из чужого примера.
@font-face {
font-family: "Project Sans Fallback";
src: local("Arial");
size-adjust: 98%;
ascent-override: 92%;
descent-override: 24%;
line-gap-override: 0%;
}
body {
font-family: "Project Sans", "Project Sans Fallback", sans-serif;
}
После настройки сравните переносы на нескольких ширинах экрана. Особенно чувствительны заголовки в две строки, кнопки с фиксированной высотой и карточки, выровненные по нижней границе. Не маскируйте проблему жёсткой высотой текстового блока: при увеличении масштаба или переводе текст может обрезаться.
Проверяемый чек-лист
| Проверка | Критерий | Если не выполнено |
|---|---|---|
| Формат | Современные браузеры получают WOFF2 | Пересобрать файлы и удалить неиспользуемые варианты |
| Начертания | Загружаются только реально применяемые веса и стили | Сверить CSS и фактическую отрисовку |
| Preload | Критичный файл стартует рано и не запрашивается повторно | Сопоставить URL, CORS и type |
| Subset | Все символы страницы присутствуют в нужной гарнитуре | Расширить набор глифов или unicode-range |
| Показ текста | Значимый текст не остаётся невидимым | Пересмотреть font-display и порядок загрузки |
| Стабильность | Подмена не меняет критичные переносы и размеры элементов | Настроить fallback и его метрики |
| Кеш | Повторный визит не передаёт неизменившийся файл заново | Проверить заголовки кеширования и версионирование URL |
Типовые ошибки
- Предзагрузка всех начертаний без проверки, появляются ли они в первом экране.
- Одновременное подключение локальных файлов и внешнего провайдера для одной гарнитуры.
- Несовпадение веса в CSS: файл объявлен как
400, а элемент запрашивает500. - Latin-subset на русскоязычной странице, из-за которого разные алфавиты выглядят неодинаково.
- Использование
font-display: swapбез настройки метрик запасного шрифта. - Проверка только при быстром соединении и прогретом кеше.
- Размещение важных иконок в шрифте: до его загрузки смысл кнопки может быть неясен.
Границы метода
Настройки шрифтов не устраняют задержки, вызванные медленным сервером, тяжёлым JavaScript, общей цепочкой блокирующих стилей или большим объёмом изображений. Preload не ускорит файл, который уже обнаруживается достаточно рано, а subset не поможет, если задержка возникает до запроса ресурса. Эти причины требуют отдельной диагностики скорости страницы.
Кроме того, публичная проверка не раскрывает процесс сборки, лицензионные условия и исходные файлы гарнитуры. Их нужно проверять внутри проекта. Снаружи можно оценить итоговую разметку, сетевые запросы, применённые стили и наблюдаемое поведение текста.
Итог
Надёжная оптимизация шрифтов сайта строится в таком порядке: определить реально используемые файлы, обеспечить раннее обнаружение критичного начертания, сократить набор глифов без потери нужных символов, выбрать подходящий font-display и согласовать метрики fallback-шрифта. После каждого изменения результат следует проверять при холодном кеше, медленной сети и нескольких ширинах экрана.
SiteVisor анализирует публичный URL без доступа к CMS и проверяет технические, SEO/GEO и конверсионные сигналы. Чтобы получить дополнительную независимую картину страницы, можно запустить бесплатную проверку. Другие практические материалы собраны в блоге SiteVisor.