Веб-шрифт может сделать сайт выразительным, а может стать причиной задержки первого текста. Проблема почти никогда не в самом факте использования шрифта. Обычно тормозит цепочка: слишком большой файл, лишние начертания, неподходящий формат, неправильный preload или стратегия, при которой браузер долго ждёт файл перед показом текста.
Главная мысль простая: для сайта рабочий исходник и доставочный файл - разные вещи. TTF или OTF удобны для архива, дизайна и установки в систему, а в браузер чаще нужно отдавать WOFF2. Спецификация WOFF2 описывает его как веб-формат с преобразованиями данных шрифта и Brotli-сжатием. Это не "новый дизайн шрифта", а компактная упаковка для доставки.
Что именно тормозит
Когда страница открывается, браузер сначала строит HTML и CSS, затем понимает, какие шрифты нужны, скачивает файлы и решает, показывать ли текст сразу fallback-шрифтом или ждать webfont. Если файл большой, лежит далеко, не кэшируется или подключён слишком поздно, пользователь видит либо пустое место, либо позднюю замену шрифта.
web.dev в гайде по оптимизации веб-шрифтов подчёркивает ту же идею: загрузка шрифтов должна быть частью performance-бюджета, а не декоративной деталью после верстки. Важно управлять не только файлом, но и тем, когда браузер узнаёт о нём.
Формат: почему WOFF2 почти всегда первый выбор
TTF и OTF стоит хранить как рабочие и архивные форматы. Но если речь о production-сайте, пользователь не должен скачивать исходник без необходимости. WOFF2 обычно меньше и лучше подходит под модель CSS `@font-face`.
| Формат | Где держать | Почему |
|---|---|---|
| TTF / OTF | Архив, дизайн, установка в ОС | Удобны для редакторов, передачи исходника и локальной установки |
| WOFF | Запасной веб-формат | Полезен только если нужна поддержка старых браузеров |
| WOFF2 | Основная веб-доставка | Современная компактная упаковка, описанная в W3C WOFF2 |
| Variable WOFF2 | Большие семейства и адаптивная типографика | Один файл может заменить набор статических начертаний, если реально нужны оси вариации |
Практическое правило: если сайт подключает только современные браузеры, начинайте с WOFF2. Если нужна очень широкая совместимость, добавляйте WOFF вторым источником, но не превращайте fallback в набор из пяти форматов "на всякий случай".
Subset: не отправляйте весь Unicode без причины
Большой многоязычный шрифт может включать латиницу, кириллицу, греческий, CJK, символы, лигатуры и декоративные наборы. Если конкретной странице нужна только кириллица и базовая латиница, весь файл может быть лишним. Subset решает эту задачу: в доставочный файл попадает только нужная часть глифов и таблиц.
CSS помогает разделять подмножества через `unicode-range`; этот descriptor описан в MDN для `@font-face/unicode-range`. Браузер может скачать только тот файл, который покрывает реально встреченные символы.
Пример логики:
| Подмножество | Что входит | Когда скачивается |
|---|---|---|
| latin-basic | A-Z, a-z, цифры, базовая пунктуация | Если на странице есть латиница |
| cyrillic | А-Я, а-я, Ё/ё, русская пунктуация | Если на странице есть кириллица |
| symbols | ₽, №, стрелки, спецсимволы | Только там, где эти знаки реально нужны |
| full | Все глифы семейства | Для скачивания исходника, но не как основной webfont |
Ошибка здесь часто одна: сделать subset, но забыть важные символы. Для русскоязычного сайта обязательно проверяйте `Ё`, `ё`, `№`, `₽`, кавычки, тире и реальные фразы интерфейса.
`font-display`: что увидит человек, пока файл грузится
`font-display` управляет тем, как браузер показывает текст в период загрузки webfont. Descriptor описан в CSS Fonts Module Level 4. На практике чаще всего выбирают `swap`, `fallback` или `optional`.
| Значение | Поведение | Когда выбирать |
|---|---|---|
| `block` | Браузер может скрывать текст, ожидая шрифт | Почти никогда для обычного контента |
| `swap` | Текст быстро появляется fallback-шрифтом, затем заменяется | Брендовый шрифт важен, но текст должен быть виден сразу |
| `fallback` | Короткое ожидание, затем fallback; поздняя замена ограничена | Хороший баланс для статей и интерфейсов |
| `optional` | Браузер может оставить fallback, если шрифт не успел | Для неключевых декоративных шрифтов |
Для статьи, каталога или интерфейса обычно лучше видимый текст с аккуратной заменой, чем пустое место. Если шрифт меняет ширину строк, подберите fallback-стек и метрики, иначе поздняя замена может сдвинуть контент.
Preload: ускоряет только нужные файлы
`<link rel="preload">` сообщает браузеру о критическом ресурсе раньше, чем он был бы найден обычным путём. MDN описывает preload как способ заранее загрузить ресурс, который понадобится текущей навигации: rel=preload.
Для шрифтов важно указывать `as="font"`, тип и `crossorigin`. Даже если файл на том же домене, шрифты часто идут через CORS-режим; без корректного `crossorigin` можно получить повторную загрузку.
```html <link rel="preload" href="/fonts/inter-cyrillic.woff2" as="font" type="font/woff2" crossorigin > ```
Но preload - не кнопка "сделать быстрее всё". Если preload поставить на каждое начертание, браузер начнет конкурировать за сеть ещё до того, как поймёт, что действительно нужно. Preload нужен только для критического шрифта первого экрана: обычно regular и, если необходимо, bold.
Рабочий рецепт подключения
Сначала выберите только те начертания, которые реально используются. Затем сделайте subset, соберите WOFF2 и подключите через `@font-face`. После этого добавьте preload только на критические файлы и проверьте результат в Network/Performance.
```css @font-face { font-family: "Site Text"; src: url("/fonts/site-text-cyrillic.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: fallback; unicode-range: U+0400-04FF, U+0020-007E; }
body { font-family: "Site Text", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; } ```
Этот пример не универсальный шаблон, а направление: ограничить файл, явно описать вес и стиль, выбрать стратегию отображения, оставить хороший fallback.
Что проверять перед выкладкой
| Проверка | Как понять, что всё нормально |
|---|---|
| Размер файлов | WOFF2 не тащит лишние языки и начертания; самый важный файл не выглядит как полный исходник |
| Количество запросов | Для первого экрана не скачивается всё семейство сразу |
| Preload | Есть только у критических шрифтов; нет duplicate-download из-за CORS |
| `font-display` | Текст не пропадает на медленной сети |
| Fallback | Замена шрифта не ломает строки и кнопки |
| Символы | Кириллица, `Ё`, `ё`, `№`, `₽`, кавычки и тире отображаются из нужного subset |
| Метрики | Нет заметного скачка высоты строк после загрузки |
web.dev в best practices по шрифтам отдельно связывает работу со шрифтами с пользовательскими метриками: важно не только скачать файл, но и не ухудшить рендер и стабильность макета.
Частые ошибки
Первая ошибка - отдавать TTF напрямую в браузер, потому что "он уже есть". Для сайта лучше собрать WOFF2.
Вторая - подключать все веса: Light, Regular, Medium, Semibold, Bold, Black, Italic, даже если в интерфейсе используются только Regular и Bold. Каждый лишний файл конкурирует за сеть и кэш.
Третья - ставить `font-display: block` на текстовый сайт. Пользователь пришёл читать, а не ждать идеальную гарнитуру.
Четвёртая - делать subset только по латинице и случайно потерять кириллицу, `Ё`, знак рубля или кавычки. Это особенно заметно в каталогах шрифтов и редакторских материалах.
Итог
Быстрый веб-шрифт - это не один приём, а цепочка решений: исходник хранится как TTF/OTF, сайт получает WOFF2, файл уменьшается через subset, критичный ресурс может получить preload, а `font-display` решает, что увидит человек до завершения загрузки. Хорошая типографика в вебе начинается не с красивого названия гарнитуры, а с аккуратной доставки.