Шрифты и CSS: четыре мелкие оптимизации одним сборником
Шрифты и CSS: четыре мелкие оптимизации одним сборником
Четыре оптимизации, которые стоят в конце любого чек-листа: локальные шрифты вместо Google Fonts, preload ключевых ресурсов, font-display и критический CSS. По отдельности каждая даёт 50–300 мс, вместе — заметное ускорение первой отрисовки. Разбираю каждую: что даёт, как настроить, где грабли. Проверено на живых сайтах (включая сайт с системными шрифтами — для него половина списка неактуальна, и это тоже результат).
1. Локальные Google Fonts
Зачем: два внешних запроса (fonts.googleapis.com за CSS + fonts.gstatic.com за woff2) — это DNS, TLS и загрузка с чужого домена. Плюс IP посетителя уходит в Google — в EU за это штрафовали (LG Schleswig-Holstein, 2022), в РФ претензий к Google Fonts пока нет, но логика та же.
Как:
- Скачать нужные woff2 (Google Fonts → выбрать начертания → «Download family»; хватит regular/italic/bold/700).
- Положить в
wp-content/themes/тема/fonts/. - В CSS темы —
@font-faceс локальными путями:
@font-face {
font-family: 'PT Serif';
src: url('fonts/ptserif-regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
- Удалить старое подключение из functions.php (
wp_enqueue_style('fonts.googleapis…')или<link href="https://fonts.googleapis.com/css2?…">в header.php).
Проверка: DevTools → Network → фильтр «googleapis» и «gstatic» — должно быть пусто. Если тема тянет шрифты через кастомайзер или плагин — отключить именно этот источник.
Грабли: скачать только используемые начертания (кириллица + латиница regular/italic/bold — 4–6 файлов на семейство, не 18); woff2 вместо woff/ttf (вдвое-втрое меньше).
2. Preload шрифтов и LCP-картинки
Браузер видит шрифт только после разбора CSS — задержка 100–300 мс на каждый шрифт. preload говорит браузеру качать параллельно с HTML:
add_action( 'wp_head', function () {
?>
<link rel="preload" href="/wp-content/themes/тема/fonts/ptserif-regular.woff2" as="font" type="font/woff2" crossorigin>
<?php
}, 5 );
Нюансы:
crossoriginобязателен даже для своих шрифтов (иначе двойная загрузка).- Preload только реально используемых на этой странице шрифтов: preload неиспользуемого шрифта — штраф, а не ускорение.
- Для LCP-картинки (первая крупная на экране) в WP 6.3+ ядро само ставит
fetchpriority="high"— проверьте в DevTools, что она грузится в первой волне.
Эффект: текст и LCP-картинка стартуют на 100–300 мс раньше; на медленной мобильной сети — больше.
3. font-display: swap
Пока шрифт грузится, браузер скрывает текст (FOIT — вспышка невидимого текста) или показывает системный (FOUT — скачок шрифтов). font-display управляет этим:
| Значение | Поведение | Когда |
|---|---|---|
| auto | на усмотрение браузера (обычно FOIT ~3 с) | — |
| block | невидимый текст до 3 с | не рекомендую |
| swap | текст сразу системным шрифтом, замена после загрузки | текстовые шрифты |
| optional | шрифт только если успел за ~100 мс; иначе системный до следующей загрузки | декоративные |
Для текстовых — swap. Нюанс: при поздней замене текст «прыгает» (layout shift) — лечится size-adjust и метрическими аналогами (fontaine/wpb метрики), но на практике для блога достаточно swap + близкие по ширине системные фолбэки.
Для Google Fonts параметр уже в URL: fonts.googleapis.com/css2?family=…&display=swap — проверить, что он там есть.
4. Критический CSS
Каждый stylesheet в <head> — render-blocking: рендер ждёт полной загрузки и разбора CSS. На медленной мобильной сети 100 КБ CSS — это 0,5–1 с до первого пикселя.
Приём: стили первого экрана (шапка, типографика, сетка первой вьюпорта — обычно 5–15 КБ) инлайнятся в <style> прямо в <head>, полный CSS загружается асинхронно:
<style>/* критические стили первого экрана */</style>
<link rel="preload" href="style.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="style.css"></noscript>
Как собрать: инструменты penthouse/critical (node), или вручную — открыть страницу, показать отрендеренные стили, вырезать первый экран. Инструмент WP-Optimize (Pro-функция «Критический CSS») делает это автоматически.
Грабли:
- Критический CSS устаревает при каждой правке дизайна — пересобирать после изменений темы; автоматика (плагин/CI) обязательна для регулярных правок.
- Инлайнить весь CSS — типичная ошибка: 200 КБ в head хуже render-blocking.
- Проверять на реальных шаблонах: критические стили, собранные для главной, не покрывают страницу записи.
Чек-лист применения (по порядку)
- Аудит: какие шрифты грузятся, откуда, с каким font-display; какие ресурсы render-blocking; есть ли preload; что такое LCP-элемент.
- Шрифты → локально с font-display: swap; preload регулярного начертания.
- LCP-картинка → preload или fetchpriority=high.
- Критический CSS первого экрана → инлайн; полный CSS — async.
- Проверка в DevTools: Network (нет render-blocking), Lighthouse (FCP/LCP), а не «на глаз».
Чего ждать по цифрам
Честно: это оптимизации на 50–300 мс каждая, не «в 20 раз». На сумме:
- FCP (первая отрисовка) −200–500 мс на мобильной сети;
- LCP −100–300 мс от preload шрифта/LCP-картинки;
- исчезновение FOIT и скачков текста — то, что видит глаз.
На фоне кэширования (−74 % веса страницы, TTFB с 3 с до 0,02 с) это вторая скрипка — но именно она отличает «быстрый сайт» от «быстрый TTFB».
