<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[280KB CSS в бандле: почему это мертвый груз]]></title><description><![CDATA[<p dir="auto">Допустим, ты открыл DevTools, глянул на размер CSS-бандла и офигел: 280 килобайт. При том, что в проде используется максимум половина селекторов. Звучит знакомо? Это не редкость — это норма для легаси-проектов и фреймворков, которые тащат за собой целый шкаф стилей “на всякий случай”.</p>
<p dir="auto">Вопрос не в том, нужна ли оптимизация. Вопрос в том, почему мы до сих пор возим с собой такой балласт. Давай разберём, как этот груз влияет на реальную производительность и что с этим делать.</p>
<h2>Когда 280KB перестают быть просто числом</h2>
<p dir="auto">Люди часто думают: ну, 280 килобайт — это же не мегабайт, какие проблемы? На десктопе с широким каналом действительно может быть не страшно. Но спустись с облаков: мобильное устройство, 4G, потерянные пакеты, задержки в сети — и вот уже парсинг CSS жрёт 800 миллисекунд процессорного времени.</p>
<p dir="auto">Чем больше CSS-файл, тем дольше браузер его парсит и применяет стили. Это не просто увеличивает время загрузки страницы — это блокирует рендеринг. CSSOM (объектная модель CSS) строится медленнее, флоу и макет пересчитываются дольше, First Contentful Paint смещается вправо на графике. Юзер смотрит на белый экран, пока браузер разбирается с твоим раздутым бандлом.</p>
<p dir="auto"><strong>Главная ловушка</strong>: неиспользуемый CSS занимает место в бандле, но браузер не знает, какие селекторы понадобятся — поэтому парсит всё. Результат: ненужные стили замораживают рендеринг.</p>
<ul>
<li>Каждый килобайт CSS = время парсинга и применения стилей</li>
<li>На мобильном оборудовании эффект усиливается в 2-3 раза</li>
<li>Неиспользуемые селекторы замораживают рендеринг, даже если они никогда не применятся</li>
</ul>
<h2>Откуда берётся этот мертвый груз</h2>
<p dir="auto">Обычно всё начинается невинно: подключил UI-фреймворк, забыл удалить исходники старого дизайна, накопилось несколько переписанных компонентов. За полгода продакшена это растёт, как ком снега. Потом приходит новый девелопер, видит готовый CSS, копирует куски в свою фичу — и вот уже 280 килобайт.</p>
<p dir="auto">Критическая ошибка — не проверять, что реально используется. Никто не ходит по всему коду и не ищет мёртвый CSS: лень, время, приоритеты. CSS не вызовет ошибку, если он не используется — просто будет сидеть в бандле и ничего не делать.</p>
<p dir="auto"><strong>Типичные источники раздутого CSS:</strong></p>
<ul>
<li>Полный импорт фреймворков (Bootstrap, Tailwind в режиме development) без tree-shaking</li>
<li>Морозный код от старых версий компонентов</li>
<li>Копипаста стилей из других проектов без адаптации</li>
<li>Экспериментальные медиа-запросы и селекторы, которые потом забыли удалить</li>
<li>Множественные переопределения одних и тех же свойств</li>
</ul>
<h2>Инструменты для поиска и удаления мусора</h2>
<p dir="auto">Хорошая новость: это реально найти и убрать. Плохая: нужно быть внимательным и не сломать при этом ничего.</p>
<p dir="auto">Существуют инструменты, которые анализируют используемые селекторы и помечают orphan-CSS. PurgeCSS и аналоги сканируют твой HTML, JS и помечают селекторы, которые ни разу не встретились в коде. Звучит просто, но есть трюки: динамические классы, которые генерируются в runtime, инструменты могут не увидеть. Поэтому любой автоматический анализ нужно перепроверять вручную.</p>
<p dir="auto"><strong>Реальный процесс очистки:</strong></p>
<ol>
<li>Запусти PurgeCSS или аналог (PostCSS purge, cssnano) и посмотри, что он найдёт</li>
<li>Включи в конфиг всех твоих компонентов и динамические паттерны (например, <code>btn-*</code> для утилит)</li>
<li>Минифицируй результат через cssnano или swc</li>
<li>Добавь тесты: убедись, что ничего не сломалось визуально</li>
<li>Повтори через месяц-два: код растёт, новый мусор накапливается</li>
</ol>
<p dir="auto">Использование <strong>автоматического tree-shaking</strong> при импорте CSS — это не фишка, а обязательное условие. Если ты подключаешь стили через модули (CSS-in-JS, SCSS imports), убедись, что бандлер именно tree-shakит неиспользуемые селекторы. Иначе весь фреймворк поедет в prod.</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Инструмент</th>
<th>Что делает</th>
<th>Подходит для</th>
</tr>
</thead>
<tbody>
<tr>
<td>PurgeCSS</td>
<td>Анализирует код, ищет orphan-селекторы</td>
<td>Любых проектов с чистой HTML-структурой</td>
</tr>
<tr>
<td>cssnano</td>
<td>Минифицирует и объединяет CSS</td>
<td>Финальной оптимизации на уровне PostCSS</td>
</tr>
<tr>
<td>Tailwind purge</td>
<td>Встроенная очистка неиспользуемых утилит</td>
<td>Проектов на Tailwind CSS</td>
</tr>
<tr>
<td>Chrome DevTools Coverage</td>
<td>Показывает неиспользуемый код прямо в браузере</td>
<td>Анализа и отладки</td>
</tr>
</tbody>
</table>
<h2>Что реально экономит: caching, splitting, loading</h2>
<p dir="auto">Когда 280 килобайт уже в бандле, оптимизация CSS переходит на второй уровень: как быстро его загрузить и примени**.** Здесь работают старые, проверенные методы.</p>
<p dir="auto">Сервер-сайд кэширование CSS-файлов с правильными заголовками (Cache-Control: max-age) экономит тысячи повторных загрузок. Версионирование через хеши в имени файла гарантирует, что обновление пойдёт только при изменении. Это база — но часто забывают настроить правильно.</p>
<p dir="auto">Разбиение CSS на несколько файлов — не волшебство, но работает: critical CSS (стили выше сгиба) инлайнится в HTML, остальное загружается асинхронно. Медиа-запросы для мобильных устройств можно загружать условно, они не блокируют рендеринг на десктопе.</p>
<p dir="auto"><strong>Практические шаги:</strong></p>
<ul>
<li>Выдели <strong>critical CSS</strong> (стили для видимой части страницы) и закинь их в <code>&lt;style&gt;</code> в <code>&lt;head&gt;</code></li>
<li>Остальной CSS загружай через <code>&lt;link rel="preload"&gt;</code> с атрибутом media для условной загрузки</li>
<li>Минифицируй каждый файл отдельно, используй Gzip или Brotli на сервере</li>
<li>Убедись, что Cache-Control установлены правильно: заголовки не нужно переусложнять</li>
<li>Посмотри LCP (Largest Contentful Paint) в Core Web Vitals — если блокируется на CSS, это виднов</li>
</ul>
<h2>Над чем стоит подумать</h2>
<p dir="auto">Чистка CSS — это не одноразовая акция, а процесс. Если ты просто удалил мусор и забыл про это, через полгода история повторится. Нужна система: регулярные проверки в CI, тесты на регрессию (visual regression testing), возможно, даже бюджет на размер бандла.</p>
<p dir="auto">И да, иногда 280 килобайт CSS — это следствие более глубокой проблемы: неправильная архитектура компонентов, отсутствие компонентной системы или просто небрежность. Оптимизация CSS — это симптом. Лечить нужно диагноз.</p>
<p dir="auto">Посмотри на свой проект честно: может, проще переписать стили для реальных нужд, чем таскать легаси? Иногда это быстрее, чем отлавливать phantom-CSS по всему коду.</p>
]]></description><link>https://forum.exlends.ru/topic/1960/280kb-css-v-bandle-pochemu-eto-mertvyj-gruz</link><generator>RSS for Node</generator><lastBuildDate>Wed, 20 May 2026 09:37:14 GMT</lastBuildDate><atom:link href="https://forum.exlends.ru/topic/1960.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 26 Mar 2026 11:33:18 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to 280KB CSS в бандле: почему это мертвый груз on Thu, 26 Mar 2026 20:10:42 GMT]]></title><description><![CDATA[<p dir="auto">Есть аналог PurgeCSS только чтобы  искал функции, компоненты?</p>
]]></description><link>https://forum.exlends.ru/post/2884</link><guid isPermaLink="true">https://forum.exlends.ru/post/2884</guid><dc:creator><![CDATA[Aladdin]]></dc:creator><pubDate>Thu, 26 Mar 2026 20:10:42 GMT</pubDate></item></channel></rss>