Объединение CSS в эпоху HTTP/2: нужно ли это в 2026
Концепция «склей всё в один файл» родилась во времена HTTP/1.1. В эпоху HTTP/2 и HTTP/3 правила изменились. Разбираем когда объединять, когда разбивать.
«Объединяйте все CSS в один файл — меньше запросов, быстрее сайт». Это было правилом эпохи HTTP/1.1 с её жёстким лимитом на параллельные соединения. В 2026 году, когда практически весь веб работает на HTTP/2 и активно переходит на HTTP/3, правила изменились — иногда даже в обратную сторону.
В этой статье разбираемся как правильно разбивать или объединять CSS в современной инфраструктуре.
Почему «один большой CSS» было правилом
HTTP/1.1 имеет жёсткое ограничение: 6 параллельных запросов к одному домену. Если у вас 30 CSS-файлов в head, браузер качает по 6 одновременно, остальные ждут очереди. Получается «лесенка» загрузки — общий time-to-render растёт.
Решение из эпохи 2010-х: склейте все CSS в один большой файл. Один запрос — без ожидания очереди — быстрее рендер.
Дополнительная мотивация: каждый HTTP-запрос имеет накладные расходы (handshake, заголовки). Меньше запросов — меньше overhead.
Что изменил HTTP/2
В HTTP/2 нет лимита параллельных запросов. Одно TCP-соединение, мультиплексирование, все ресурсы передаются параллельно. Накладные расходы на запрос — минимальны (HPACK сжатие заголовков).
Это убирает главную мотивацию объединения. 30 маленьких CSS-файлов и один большой 30-КБ файл загружаются примерно одинаково.
Подробнее об HTTP/2 — в посте HTTP/2 и HTTP/3 в 2026.
Но почему «не объединяй» тоже не панацея
Хотя HTTP/2 убрал ограничение, у разбивки есть свои минусы:
1. Парсинг каждого CSS — это работа браузера
Один большой файл парсится один раз. 30 маленьких — 30 итераций парсинга. На медленных CPU (бюджетный Android) это даёт суммарно 50-100 мс лишней работы.
2. Меньше эффективность сжатия (gzip/brotli)
Сжимать одну большую строку CSS эффективнее, чем 30 маленьких. Повторяющиеся паттерны (имена классов, цветовые коды, общие свойства) сжимаются лучше при большем словаре.
Типичный эффект: 30 файлов по 5 КБ → 150 КБ. Сжаты gzip → 80 КБ. Тот же контент в одном файле — gzip → 65 КБ. То есть 15 КБ экономии чисто за счёт лучшей компрессии.
3. Race conditions с переменными CSS
Если переменные определены в одном файле, а используются в другом, плюс файлы загружаются параллельно через HTTP/2 — может случиться короткий момент, когда стили частично применены без переменных. FOUC.
Что выбирать в 2026
Зависит от ситуации.
Стратегия «critical + bundle» (рекомендуем)
- Inline critical CSS в HTML — 5-15 КБ стилей для above-the-fold
- Один bundle CSS для остального — через
<link>async-загрузка
Это лучший компромисс:
- Critical CSS даёт мгновенный рендер above-the-fold
- Bundle CSS грузится параллельно с другими ресурсами
- Один большой bundle лучше сжимается
- Не нужно думать про параллелизм
Стратегия «split by route» (Next.js / SPA)
Современные React/Vue/Svelte стеки разбивают код (и CSS) по маршрутам. Каждая страница тянет свой chunk.
В Next.js это работает автоматически. Главная страница тянет main CSS + page CSS, страница /blog/ — main CSS + blog page CSS. Кешированный main CSS не запрашивается повторно.
Плюс: пользователь, который кликает по разделам, тянет только новые куски. Меньше дублирующих загрузок.
Минус: первый визит на одну страницу тянет больше отдельных файлов.
В HTTP/2 — это норма. В HTTP/1.1 был антипаттерн.
Стратегия «один файл на всё» (для совсем простых сайтов)
Для лендингов на 1-3 страницы — оправдано. Один CSS, кешируется на год, всё работает.
Не стоит делать для больших сайтов и SPA — в них всегда есть страничный контент, который не нужен всем.
Brotli > Gzip — отдельная история
Независимо от стратегии разбивки, переход с gzip на brotli даёт +15-25% сжатия для CSS. В 2026 году Brotli поддерживают все актуальные браузеры.
В nginx:
brotli on;
brotli_comp_level 6;
brotli_types text/css application/javascript text/html text/plain application/json image/svg+xml;
Это бесплатное ускорение, не зависит от стратегии разбивки.
Что не делать
- Слепо склеивать всё в один CSS на сайте с 100+ страницами разной тематики. Получите 500 КБ CSS, из которых на любой странице используется 20 КБ. Tree-shaking через PurgeCSS — обязательная гигиена.
- Разбивать на десятки крохотных файлов просто «для модульности». Имеет смысл разбивать по бизнес-логике (главная, каталог, корзина, профиль), а не по каждому компоненту.
- Зависеть от @import-цепочек — они блокируют рендер последовательно. См. отдельный материал про @import в CSS.
Реальные замеры
Тестовый сайт, 200 КБ суммарного CSS, страница содержит ссылки на:
Конфигурация A: 1 CSS-файл 200 КБ
- LCP: 1.4 сек
- TTI: 2.1 сек
Конфигурация B: 12 CSS-файлов по 15 КБ через HTTP/2
- LCP: 1.5 сек
- TTI: 2.3 сек
Конфигурация C: critical inline (15 КБ) + 1 async bundle (185 КБ)
- LCP: 0.9 сек
- TTI: 1.8 сек
Разница между A и B — в пределах погрешности. Конфигурация C даёт значимый выигрыш именно за счёт inline critical, не за счёт разбивки.
Резюме
В эпоху HTTP/2 правило «склей всё в один файл» больше не догма. Главное — не количество файлов, а:
- Inline критического CSS для above-the-fold
- Async-загрузка остального
- Brotli-сжатие
- PurgeCSS или подобная чистка от неиспользуемых стилей
Любой современный сборщик (Webpack, Vite, esbuild) это умеет. Не нужно вручную «склеивать» или «разбивать» — настройте build-pipeline один раз.
Хотите аудит CSS-стратегии вашего сайта? Напишите нам. Бесплатно за 2 рабочих дня.