Оптимизация шрифтов для 1С-Битрикс
Шрифты — один из самых недооценённых источников задержки при загрузке страниц. На типичном Битрикс-проекте встречается ситуация: сайт подключает 4–6 начертаний Google Fonts через @import прямо в CSS, каждый @import блокирует рендер, браузер ждёт CSSOM, а пользователь видит пустую страницу или «мигание невидимого текста» (FOIT). В Lighthouse это фиксируется как «Ensure text remains visible during webfont load» и напрямую бьёт по метрике LCP.
Как Битрикс подключает шрифты по умолчанию
В большинстве тем шрифты подключаются одним из трёх способов:
-
@import url('https://fonts.googleapis.com/...')внутриtemplate_styles.css— самый медленный вариант: браузер обнаруживает запрос только после скачивания CSS. -
<link>вheader.phpшаблона без атрибутовpreconnectиpreload. - Прямое подключение
.woff/.woff2через CDN без кэширующих заголовков.
Битрикс не управляет шрифтами через ядро — всё живёт в шаблоне, поэтому менять нужно именно там, а не через настройки модуля main.
Ключевые техники оптимизации
Self-hosted шрифты вместо Google Fonts
Загрузка шрифтов с внешнего CDN добавляет DNS-lookup + TCP handshake + TLS negotiation — суммарно от 100 до 300 мс на холодном соединении. Переносим шрифты на свой сервер:
# Скачиваем через google-webfonts-helper или npx
npx google-webfonts-helper --family="Roboto" --subsets="latin,cyrillic" --variants="400,700"
Файлы кладём в /local/templates/[template]/fonts/, CSS — в fonts.css:
@font-face {
font-family: 'Roboto';
src: url('/local/templates/main/fonts/roboto-400.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
unicode-range: U+0400-045F, U+0490-0491; /* только кириллица */
}
font-display: swap — обязательно. Без него браузер блокирует отрисовку текста до загрузки шрифта.
Preload для критических начертаний
В header.php шаблона добавляем preload для начертания, которое используется в первом экране:
// header.php
$APPLICATION->AddHeadString(
'<link rel="preload" href="/local/templates/main/fonts/roboto-400.woff2" as="font" type="font/woff2" crossorigin="anonymous">'
);
Preload работает для одного-двух начертаний. Preload всех вариантов — контрпродуктивен: браузер скачивает их с высоким приоритетом, конкурируя с HTML и критическим CSS.
Subsetting: выбрасываем лишние глифы
Полный Roboto весит 150–200 КБ на начертание. Для русскоязычного сайта нужны только latin + cyrillic. С помощью pyftsubset (fonttools):
pyftsubset roboto-regular.ttf \
--unicodes="U+0020-007E,U+0400-045F,U+0490-0491,U+00A0" \
--flavor=woff2 \
--output-file=roboto-400-subset.woff2
Результат — файл 20–35 КБ вместо исходных 150+ КБ.
variable fonts
Если дизайн использует несколько начертаний одной гарнитуры (Regular, Medium, Bold), рассмотрите variable font — один файл заменяет несколько:
@font-face {
font-family: 'Roboto';
src: url('/fonts/Roboto-VF.woff2') format('woff2 supports variations'),
url('/fonts/Roboto-VF.woff2') format('woff2');
font-weight: 100 900;
font-display: swap;
}
Variable font Roboto весит ~75 КБ и покрывает все веса — против 4×30 КБ = 120 КБ для отдельных файлов с subsets.
Кейс: интернет-магазин строительных материалов
Магазин на Битрикс «Бизнес» подключал 3 семейства через Google Fonts: Roboto (3 начертания), Open Sans (2), Oswald (1). Итого 6 HTTP-запросов к fonts.googleapis.com + 6 запросов к fonts.gstatic.com. render-blocking задержка составляла 480–620 мс, LCP на мобильных — 4,8 с.
После переноса на self-hosted с subsetting и одним preload для Roboto 400:
- LCP снизился до 2,1 с
- Суммарный вес шрифтов: с 820 КБ до 94 КБ
- Render-blocking шрифтов: 0 мс (благодаря
font-display: swap+ preload)
Работы заняли 2 дня: анализ текущего подключения, подготовка subset-файлов, правка header.php и fonts.css, тестирование в Lighthouse и WebPageTest.
Диагностика проблем
Быстрая проверка через DevTools: вкладка Network → Font. Если в столбце Initiator написано stylesheet (а не preload), шрифт загружается реактивно, а не проактивно. Метрика FCP в Lighthouse ниже 1,8 с при наличии render-blocking шрифтов — практически недостижима без описанных оптимизаций.
Сроки
| Масштаб | Состав | Срок |
|---|---|---|
| Базовый | Self-hosted + font-display: swap + preload |
1–2 дня |
| Полный | Subsetting, variable fonts, аудит всех шаблонов, настройка заголовков кэширования | 3–5 дней |







