Перейти к основному содержимому

Разработка 21 октября 2026г. 8 мин чтения

Свои шрифты вместо Google Fonts: 474 КБ превратились в 135

Подключённый Google Fonts ставит в критический путь два чужих домена подряд: сначала домен со стилями отдаёт описание шрифта, и только потом начинается запрос к домену с файлами. Мы скачали шрифты, урезали их под кириллицу и собрали свой файл стилей: 8 начертаний уложились в 135 килобайт против 474 у нарезки Google. Рассказываем, как прошёл перенос и что мы чуть не потеряли по дороге.

Подключённый Google Fonts ставит в критический путь два чужих домена подряд: сначала домен со стилями отдаёт описание шрифта, и только потом начинается запрос к домену с файлами. Мы скачали шрифты, урезали их под кириллицу и собрали свой файл стилей: 8 начертаний уложились в 135 килобайт против 474 у нарезки Google. Рассказываем, как прошёл перенос и что мы чуть не потеряли по дороге.

Мы не планировали заниматься шрифтами отдельно - искали, откуда берутся лишние секунды до отрисовки текста на мобильном. LCP-элементом оказался не баннер, а подзаголовок первого экрана: он ждал шрифт, а шрифт - ответа от двух чужих серверов. Подробно о метриках писали в статье про Core Web Vitals, здесь - только про шрифты.

Почему два чужих домена тормозят даже быстрый хостинг

Строка вида <link href="https://fonts.googleapis.com/css2?family=..."> выглядит безобидно, но за ней скрыты два похода в сеть. Сначала браузер соединяется с fonts.googleapis.com и получает CSS-файл с описанием шрифта: какие начертания есть и где лежат файлы. Только после этого браузер узнаёт настоящий адрес на fonts.gstatic.com и идёт туда за самими файлами.

Каждое из этих обращений - это DNS-резолв, TLS-рукопожатие и сам запрос. И так дважды, для каждого домена. На быстром хостинге собственный сервер отвечает за миллисекунды, а два чужих домена подряд всё равно добавляют к отрисовке текста заметную задержку, и от качества вашего хостинга это не зависит.

preconnect в head помогает частично: браузер заранее устанавливает соединение с обоими доменами, чтобы не тратить на это время позже. Но он не убирает сам поход за CSS-файлом и не ускоряет получение файла шрифта - лишь параллелит то, что всё равно идёт последовательно: сначала узнать адрес файла, потом скачать его. preconnect у нас стоял и до переноса. Проблему это не сняло.

Независимость от чужого сервиса - отдельный довод

Скорость - не единственная причина переноса. Пока шрифты лежат на чужом домене, отрисовка текста зависит от того, ответит ли он вообще, причём быстро и без сбоев. Для российской аудитории это не абстрактный риск: скорость и доступность зарубежных сервисов время от времени скачут, а шрифт - не то место, где хочется зависеть от чужой инфраструктуры.

Мы разбирали похожую логику в статье про CDN для сайта: там ускорение чаще выигрывает у независимости, потому что вес отдаваемых файлов большой. Со шрифтами наоборот - вес маленький, а независимость важнее выигрыша в доли секунды от чужой сети доставки контента.

Порядок действий: скачать шрифт и собрать свой файл стилей

Мы прошли перенос в пять шагов.

Скачать оригинальные файлы. У большинства шрифтов Google Fonts есть открытый исходник - полный набор начертаний в формате TrueType. Нужен именно оригинал, а не то, что отдаёт CDN: сервис режет шрифт на части сам, а нам требовался цельный файл, из которого можно вырезать свой набор символов.

Сделать сабсет под нужные языки. Из полного шрифта, где бывает по несколько тысяч символов на десятки языков, мы вырезаем только то, что реально используется: кириллицу, латиницу, цифры, базовую пунктуацию и типографические знаки вроде тире и кавычек. Чем уже набор, тем меньше весит файл.

Собрать свой @font-face. Вместо запроса к чужому CSS-файлу мы печатаем описание каждого начертания прямо в HTML: путь к файлу, вес, стиль, font-display. Один файл на начертание - в нарезке Google на одно начертание могло приходиться сразу несколько файлов под разные диапазоны символов.

Выставить font-display. Значение swap показывает текст системным шрифтом, пока грузится свой, и подменяет его без задержки. Без этого браузер может держать текст невидимым, пока файл не долетит, а при плохой сети это выглядит хуже, чем временная подмена начертания.

Предзагрузить только первый экран. Через <link rel="preload"> браузер начинает качать файл шрифта раньше, чем дойдёт до него в CSS. Предзагружать все 8 начертаний бессмысленно: на первом экране обычно видно одно-два, остальные подгрузятся, когда понадобятся.

Грабля с форматом: сервер присылает не то, что ждёшь

Первая неожиданность случилась на этапе скачивания. Сервер Google Fonts отдаёт разные форматы файла в зависимости от того, каким браузером представился скачивающий: современным браузерам достаётся woff2, старым - другие форматы, вплоть до устаревших. Инструменты для сабсета читают TrueType или OpenType, а старый формат они не понимают вообще.

Мы наткнулись на это, когда скрипт скачивания представился старым браузером: сервер прислал файл в формате, который библиотека сабсета не умеет открывать, и сборка падала на первом же шаге. Решение простое, но неочевидное: запрашивать файлы с User-Agent старого мобильного Android, тогда сервер отдаёт обычный TrueType, из которого без проблем режется нужный набор символов.

Пропавшие глифы и почему это не потеря

Вторая неожиданность - после сборки в собственном шрифте не оказалось знака рубля, стрелки, галочки и неразрывного дефиса. Первая мысль: сабсет вырезал лишнее. На деле этих знаков не было и в оригинальном файле Google: гарнитура просто не покрывает их, и раньше браузер незаметно подставлял их из системного шрифта, а после переноса продолжает делать то же самое.

Визуально ничего не изменилось, но проверить стоило отдельно: символ из системного шрифта может немного отличаться по начертанию и толщине штриха от основного текста рядом. Мы прогнали по страницам знаки, которые реально встречаются в текстах - рубль, стрелка, галочка, неразрывный дефис, кавычки, - и сравнили начертание до и после переноса. Разницы не нашли, но для сайта с ценами в рублях эту проверку стоит делать заранее, а не после вопроса от клиента.

Сколько получилось: 135 килобайт против 474

У нас получилось 8 начертаний общим весом 135 килобайт против 474 у нарезки Google при том же наборе символов. Разница в 3,5 раза. В основном дело в том, как режут файлы: Google делит каждое начертание на несколько файлов по диапазонам символов, браузер докачивает то один, то другой в зависимости от того, что встретилось на странице, а служебные заголовки дублируются в каждом файле. Мы собрали ровно один файл на начертание сразу с кириллицей, латиницей и нужными знаками - меньше файлов, меньше отдельных запросов, меньше повторяющихся служебных данных.

Два начертания первого экрана мы дополнительно вынесли в preload, остальные шесть подгружаются по мере необходимости - в подвале, в карточках, в модальных окнах.

Когда своя шрифтовая инфраструктура не нужна

Перенос шрифтов оправдан не для каждого сайта. Системный шрифт - тот, что уже установлен на устройстве читателя, - даёт ноль сетевых запросов и мгновенную отрисовку текста, потому что браузеру ничего не нужно скачивать. Для внутреннего сервиса, панели администратора или проекта, где фирменная типографика не критична, это правильный выбор, а не компромисс.

Свой шрифт стоит городить, когда гарнитура - часть узнаваемости бренда и видна на первом экране: заголовки на лендинге, логотип текстом, крупные цифры в цене. О том, как вообще выбирать и лицензировать шрифт для сайта, писали в статье про шрифты - перенос к себе имеет смысл обсуждать уже после того, как гарнитура выбрана и куплена лицензия на веб-встраивание.

Чек-лист: как перенести шрифты и не потерять кириллицу

Восемь пунктов, коротко.

  • Оригинальный файл шрифта, а не нарезка с чужого CDN.
  • Сабсет под нужный язык и типографические знаки - шире, чем просто буквы и цифры.
  • Формат ответа сервера при скачивании: не тот User-Agent - не тот формат, инструмент сабсета его не прочитает.
  • Список символов, которые реально встречаются в текстах: рубль, стрелка, галочка, неразрывный дефис, кавычки.
  • @font-face с font-display: swap, чтобы текст не пропадал на время загрузки.
  • Предзагрузка только начертаний первого экрана, остальное - на обычную загрузку.
  • Итоговый вес после сборки: если он вырос, а не упал, сабсет сделан неправильно.
  • Остальные технические пункты разом: у нас есть чек-лист технического SEO-аудита на 47 пунктов, шрифты - лишь один из них.

Своя гарнитура вместо чужого домена

Перенос шрифтов к себе - не про экономию на чужом CDN, а про то, чтобы убрать из критического пути два лишних похода в сеть и не зависеть от чужого домена. У нас 8 начертаний ужались с 474 до 135 килобайт: редкий случай, где работа на день даёт заметный эффект в замере. Пропавшие глифы и формат ответа сервера - единственные грабли, которые стоит проверить заранее, а не после вопроса от клиента. Если типографика на сайте не бренд-критична, системный шрифт остаётся нормальным выбором - переносить нечего.

Если сейчас прикидываете бюджет на новый сайт и хотите понимать, из чего складывается его техническая часть помимо дизайна, посчитайте вилку в калькуляторе стоимости: такие доработки не видны на макете, но входят в объём работ и влияют на скорость сайта.

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

Правда ли, что Google Fonts тормозит любой сайт?

Не любой и не всегда, но если шрифт - единственный источник задержки перед отрисовкой текста, то да, заметно. Два похода в сеть на чужие домены добавляют время даже на быстром хостинге, потому что дело не в вашем сервере, а в скорости ответа fonts.googleapis.com и fonts.gstatic.com.

Нужно ли переносить шрифты на каждом сайте?

Нет. Если типографика не критична для бренда и не видна крупно на первом экране, системный шрифт остаётся нормальным выбором: он не требует ни скачивания, ни сабсета и отрисовывается мгновенно.

Сколько времени занимает перенос шрифтов к себе?

На типовом наборе из 8 начертаний под кириллицу перенос занимает от нескольких часов до одного рабочего дня вместе с проверкой глифов и веса файлов. Основное время уходит не на скачивание, а на сверку, что после сабсета ничего не пропало.

Что делать, если после переноса пропал нужный символ?

Сначала проверить, был ли он в оригинальном файле шрифта: если нет, дело не в сабсете, и браузер и раньше подставлял его из системного шрифта. Если символ был в оригинале, а после сабсета исчез, значит его не включили в список нужных диапазонов - список нужно расширить и пересобрать файл.

Нужен сайт по этой теме?

Расскажите о задаче – вернёмся с расчётом и предложением структуры.