Перейти к содержанию
Innovialabs

Веб-шрифты: как подключать быстро и без скачков вёрстки

Практика3 мин

Коротко

Отдавайте шрифты в WOFF2 со своего домена, разбивайте их на подмножества по unicode-range, предзагружайте только главный файл, задайте font-display и подгоните метрики запасного шрифта — тогда текст появится сразу, а вёрстка не прыгнет.

Короткий ответ

Шрифты тормозят сайт двумя способами: текст долго не появляется, а когда шрифт загрузился — строки меняют ширину и высоту, и страница прыгает (это ухудшает метрику CLS). Рецепт:

  1. Формат WOFF2.
  2. Сабсеттинг: только нужные символы, кириллица и латиница отдельными файлами.
  3. Self-hosting на своём домене.
  4. preload для одного-двух ключевых файлов.
  5. font-display, подходящий задаче.
  6. Подгонка метрик запасного шрифта, чтобы замена была незаметной.

WOFF2 и меньше начертаний

WOFF2 сжимает шрифты лучше старых форматов и поддерживается всеми актуальными браузерами. TTF и EOT в 2020-х подключать не нужно.

Главная экономия — в количестве файлов. Каждое начертание (400, 500, 700, курсив) — отдельная загрузка. Если шрифт есть в формате variable font, один файл заменит несколько начертаний. Проверьте дизайн: часто хватает двух-трёх весов.

Сабсеттинг: кириллица и латиница

Полный шрифт содержит греческий, вьетнамский, символы и прочее, что вашему сайту не нужно. Разделите его на подмножества и укажите unicode-range — браузер скачает файл, только если на странице есть такие символы.

@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F;
}

@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-cyrillic.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

Для узбекской латиницы проверьте символы ‘ и ’ (U+2018, U+2019) — они должны попадать в один из диапазонов. Нарезать файлы можно утилитой pyftsubset из пакета fonttools.

Self-hosting или Google Fonts

Свой доменGoogle Fonts
СоединенияБез лишнихОтдельные домены для CSS и файлов
Кэш между сайтамиНетТоже нет: браузеры разделяют кэш по сайтам
КонтрольПолный: сабсеты, preload, заголовкиОграничен
ПриватностьЗапросы не уходят третьей сторонеЗапросы идут на внешний сервис

Раньше аргументом за Google Fonts был общий кэш, но современные браузеры изолируют кэш по сайтам, и это преимущество ушло. Поэтому чаще выгоднее хостить шрифты у себя. Фреймворки умеют делать это автоматически: например, next/font скачивает шрифты при сборке и отдаёт их с вашего домена.

preload: точечно

<link rel="preload" href="/fonts/inter-cyrillic.woff2"
      as="font" type="font/woff2" crossorigin>
  • Атрибут crossorigin обязателен даже для своего домена, иначе файл скачается дважды.
  • Предзагружайте один-два файла: основной текст и, возможно, заголовки. Preload всего подряд конкурирует с CSS и картинками.

font-display: что выбрать

  • swap — текст сразу показывается запасным шрифтом, потом заменяется. Хорош для основного текста, но без подгонки метрик даёт скачок.
  • optional — если шрифт не успел за очень короткое время, браузер остаётся на запасном. Скачков нет, но фирменный шрифт может не показаться при первом визите.
  • fallback — компромисс между ними.
  • block — прячет текст до загрузки. Для основного текста почти никогда не нужен.

Подгонка метрик запасного шрифта

Скачок происходит потому, что у Arial и вашего шрифта разная ширина букв и высота строк. Создайте «подогнанный» запасной шрифт:

@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;
}

Значения выше — пример: для каждого шрифта их нужно рассчитать по его метрикам. Это делают инструменты вроде Fontaine или Capsize, а next/font генерирует такой фолбэк сам.

Частые ошибки

  • Подключать шрифт через @import внутри CSS — это лишний последовательный запрос.
  • Грузить шесть начертаний, из которых используется два.
  • Забыть crossorigin в preload.
  • Отдавать шрифты без долгого кэширования: файлы со хэшем в имени можно кэшировать надолго.

Частые вопросы

Да. Системный стек вообще не требует загрузки и самый быстрый. Если бренд не требует конкретной гарнитуры, это разумный выбор.

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.