Автор статьи, первую часть перевода которой мы сегодня публикуем, хотел бы, чтобы читатели заранее знали о том, что избавление от ненужного CSS — это трудная задача. Если вы это читаете в надежде найти некий инструмент, запустив который, вы сможете узнать о том, какой именно CSS-код можно безбоязненно удалить из вашего проекта, то… Есть подобные инструменты, но их нужно использовать крайне осторожно, так как ни один из них не способен дать достойный ответ на вопрос о неиспользуемом CSS.



Несложно понять, что любому веб-разработчику хотелось бы взять некую утилиту, запустить её, и удалить тот ненужный CSS, о котором она сообщит. Пара минут — и сайт ускорен. Но не всё так просто. Автор этого материала полагает, что к подобным инструмента стоит относиться со здоровым скептицизмом. Ни один из них не лжёт разработчику. Эти инструменты обычно просто не обладают достаточным объёмом информации, позволяющим им выдать результаты, которым можно безоговорочно доверять. Но это не означает, что такими инструментами невозможно пользоваться. Не значит это и того, что от неиспользуемого CSS никак нельзя избавиться. Обсудим это.

Читать вторую часть

Зачем избавляться от неиспользуемого CSS?


Я полагаю, что главную причину, по которой кому-то может понадобиться избавиться от неиспользуемого CSS, можно описать с помощью следующего примера. Предположим, вы пользуетесь CSS-фреймворком (вроде Bootstrap), и в ваш проект попадает весь CSS-код этого фреймворка. А реально в проекте применяется лишь небольшая часть такого кода. Как избавиться от всего ненужного?

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

Предположим, вы загружаете 100 Кб CSS. Я бы сказал, что это много. (В тот момент, когда я это пишу, на сайте css-tricks.com используется около 23 Кб CSS. Здесь имеется довольно много страниц и шаблонов. При этом я ничего особого не делал для того, чтобы уменьшить размер CSS.) Тут у вас возникает подозрение, что некую часть из этого объёма кода вы не используете. А, может быть, вы находите некие доказательства этого. Я тут вижу причину бить тревогу. Если у вас имеется JPG-файл объёмом в 100 Кб, который можно сжать до 20 Кб, обработав его неким инструментом, то это замечательно, и это стоит сделать. Но если нечто подобное сделать с CSS, то подобное гораздо важнее. Дело в том, что CSS загружается в начале загрузки страницы и является ресурсом, блокирующим рендеринг. JPG-файлы такими ресурсами не являются.

Анализ ситуации с помощью инструментов разработчика Chrome


В окне инструментов разработчика Chrome есть вкладка Coverage. С её помощью можно узнать о том, сколько загруженного CSS и JavaScript реально используются на анализируемой странице. Например, сейчас я зашёл на css-tricks.com. Ниже показано то, что я увидел на вкладке Coverage.


Инструменты разработчика Chrome, вкладка Coverage

Здесь я вижу, что не используются 70.7% моего файла style.css. Я так думаю, что ничего плохого в этом нет. Оставшаяся незадействованной часть CSS используется на каких-то других страницах сайта. На этом сайте я не использую некую большую библиотеку стилей. Я сам написал каждую строчку CSS, поэтому я сомневаюсь в том, что в глобальном масштабе сайта 2/3 CSS оказываются не у дел.

Я предполагал, что при работе с вкладкой Coverage можно начать «запись» и побродить по сайту, наблюдая за тем, как процент неиспользуемых ресурсов падает по мере того, как в браузере выводятся различные страницы. Но, к сожалению, при обновлении страницы обновляется и содержимое вкладки Coverage. В результате это средство не особенно полезно в деле выяснения процента использования ресурсов на нескольких страницах. Возможно, это не так лишь в том случае, если анализировать одностраничное приложение.

Мне неприятно это говорить, но анализ сайта с помощью вкладки Coverage оказался практически бессмысленным занятием. То, что я увидел, эти 70.7%, представляет собой ужасную картину, которая играет на моих сомнениях, но ничего конкретного этот анализ мне не даёт, в результате мне остаётся лишь беспокоиться о том, что на моём сайте что-то не так.

Возможно, подобный анализ сайта и будет тем самым механизмом, который наведёт вас на мысль о том, что вам нужно найти и удалить CSS-код, который загружается, но в вашем проекте не используется.

Моя первостепенная проблема


В деле поиска и удаления неиспользуемого CSS-кода меня больше всего беспокоит следующее. Предположим, некто смотрит на результаты анализа и видит неиспользуемые фрагменты CSS.


Неиспользуемые фрагменты CSS

Он думает: «Отлично, удаляю всё лишнее!». Лишнее удаляется, а потом оказывается, что было оно вовсе не лишним, и что его удаление привело к большим проблемам со стилизацией на всём сайте. Вот в чём тут дело: можно быть полностью уверенным в том, что некий CSS-селектор не используется, только если провести изыскания по следующему плану:

  1. Нужно проверить каждую страницу сайта с помощью инструмента наподобие вкладки Coverage.
  2. При этом нужно выполнить весь JavaScript-код.
  3. Сделать это надо со всеми возможными вариантами состояния приложения.
  4. И, вдобавок, надо всё это проверить и со всеми возможными вариантами используемых медиа-запросов.

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

Нечто подобное — это слишком сложно для автоматических средств анализа CSS. Они не в состоянии идеально выполнить подобные проверки, особенно если учитывать анализ сайта в ситуации неопределённости. Речь идёт, например, об исследовании проектов в различных браузерных контекстах (разные размеры экранов, разные возможности браузеров, разные браузеры), и об учёте влияния на сайт сторонних библиотек.

А сейчас я хочу показать пример того, как все те проблемы, о которых я только что рассказал, выглядят на практике.

PurifyCSS Online


Я решил попробовать оптимизировать css-tricks.com с помощью ресурса PurifyCSS Online. Ему можно передавать ссылки, а он тут же выдаёт готовый к использованию CSS. Я «скормил» этому сайту css-tricks.com и в моём распоряжении оказался новый CSS-код. Вот что получилось после того, как я этим кодом воспользовался.


Слева — обычный вид css-tricks.com. Справа — результат применения нового, «очищенного» CSS. В этом новом коде недоставало много такого, что нужно для различных страниц сайта

PurifyCSS позволяет провести анализ на основе множества ссылок (что приятно), но на css-tricks.com десятки тысяч ссылок. Многие из них ведут на аналогичные, в плане CSS, страницы, но на каждой из таких страниц может быть что-то такое, что в других местах не используется. Кроме того, у меня появилось такое ощущение, что PurifyCSS не запускает JS-код, так как после «очистки» моего CSS всё, что выводилось на страницы средствами JavaScript, оказалось нестилизованным. Пропали даже стили для псевдоклассов :hover.

Вероятно, я уже рассказал достаточно для того, чтобы вы поняли, что я не случайно так мало доверяю подобным инструментам.

Очистка CSS с помощью PurifyCSS как часть процесса сборки проекта


PurifyCSS, вероятно, чаще используется в роли инструмента, применяемого при сборке проекта, чем в роли онлайн-средства для очистки CSS. В документации проекта есть инструкции по его использованию при применении Grunt, Gulp и webpack. Вот, например, обработка файлов по шаблонам:

var content = ['**/src/js/*.js', '**/src/html/*.html'];
var css = ['**/src/css/*.css'];

var options = {
  // Очищенный CSS попадёт в этот файл.
  output: './dist/purified.css'
};

purify(content, css, options);

Такой подход позволяет добиться гораздо большей точности. Материалы сайта, передаваемые на анализ, могут представлять собой список, в который входит каждый шаблон, каждый фрагмент, используемый для построения страниц, каждый JavaScript-файл. Может оказаться так, что подобный список ресурсов непросто поддерживать, но это позволяет учесть всё, что можно учесть. Это, правда, не относится к содержимому страниц, лежащему в неких хранилищах (вроде блог-постов, которые хранятся в базе данных), и к стороннему JavaScript-коду, но, возможно, это в некоторых случаях и неважно, или, может быть, разработчик способен будет как-то учесть CSS-нужды подобных ресурсов.

В документации к конкуренту PurifyCSS PurgeCSS есть предупреждение, касающееся способа обработки ресурсов, используемого PurifyCSS. А именно, речь идёт о том, что PurifyCSS может работать с ресурсами любых типов, а не только с HTML и JavaScript. PurifyCSS в ходе работы анализирует все слова в файлах и сравнивает их с селекторами в CSS-коде. Каждое слово рассматривается как селектор. То есть — множество селекторов может быть ошибочно признано используемыми на сайте. Например, в текстовом наполнении файла, в обычном предложении, может присутствовать слово, соответствующее некоему CSS-селектору.

Об этой особенности PurifyCSS стоит помнить. Этот инструмент ищет CSS-селекторы в материалах сайта, применяя предельно простой алгоритм. Это, с одной стороны, толковая идея, а с другой — это довольно-таки опасно.

Сервис UnusedCSS


Ручная настройка некоего инструмента, проводимая так, чтобы этот инструмент проанализировал бы каждую страницу, чтобы он рассмотрел её со всех возможных точек зрения, это, конечно, скучная рутина. При этом такая работа должна проводиться на ежедневной основе, так как анализируемые сведения о сайте должны пополняться новыми данными по мере развития проекта. Существует один онлайн-сервис, который называется UnusedCSS. Он самостоятельно обходит страницы сайта, избавляя разработчика от массы однообразной работы. Этому сервису достаточно передать единственную ссылку на сайт.

Я оформил платную подписку на этот сервис и проанализировал с его помощью css-tricks.com. Надо признать, что после того, как я взглянул на результаты, у меня возникло такое ощущение, что выглядят они гораздо точнее, чем то, что мне доводилось видеть раньше.


Анализ css-tricks.com с помощью UnusedCSS. В отчёте говорится о том, что на сайте используется 93% от загружаемого CSS-кода. Мне это кажется близким к истине, так как я вручную написал весь CSS-код для этого сайта

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

Мне очень понравилось то, что UnusedCSS дал мне гораздо более точные результаты, чем другие инструменты. Однако в данных, выдаваемых этим сервисом, слишком много «шума», и я, к тому же, пока не знаю о том, как включить UnusedCSS в регулярно повторяющийся процесс сборки проекта и вывода его новых версий в продакшн.

Читать вторую часть

Уважаемые читатели! Сталкивались ли вы с проблемой наличия неиспользуемого CSS-кода в своих проектах?


Комментарии (11)


  1. Eirik
    27.11.2019 14:06

    За последние 15 лет работы в фронтенде я понят одну простую вещь. Пока проект маленький в этом нет смысла. А когда проект разрастается до большого, то приходит очередной северный редизайн. Потому в старом CSS уже смысла нет.

    Редизайны случаются в среднем раз в 2 года. Пишем свежий CSS, чистый и свежий.


    1. Farmatique
      28.11.2019 12:37

      Это хорошо если так как Вы описываете. А если 5 лет и никакого редизайна нет, а сайт разросся мало того что вширь, так ещё и оброс всякой гадостью типа инлайновых стилей, которые прописаны не в файлах стилей, а в огромном количестве постов и страниц внутри cms. Вот это хороший вопрос… хотя подобные статьи и инструменты все равно не решат этой проблемы


      1. Eirik
        28.11.2019 12:46

        Делали парсер, который чистил все контент блоки от инлайн стилей. Потом сравнили сколько будет стоить перебрать весь старый СSS, или написать новый под новый дизайн. Оказалось нет смысла делать такую работу при этом поддерживая старый дизай и все мутации за 6 лет. Реши сделать новый стайл гайд и перебрать весь сайт. Так и почистили.


  1. Akuma
    27.11.2019 15:06

    А от него избавляются? :)
    Пожалуй, как и сказали выше, только при полном редизайне. Ну либо если точно уверен, что «это» нигде больше не используется. Лишний Кб трафика погоды не сделает.


  1. pansom
    27.11.2019 16:03

    Использую стек технологий BEM, строю дерево и css собираю по нему. Модификаторы необходимые в работе прокидываю через deps. Верстаю и горя не знаю.


  1. ZetaTetra
    27.11.2019 18:44

    Пытаюсь делать на проекте:
    Глобальный.css (Идея «светлого будущего» — дублировать глобальный.css на домены 3го уровня)
    А мелкие.css для разных разделов.

    В итоге бывают коллизии, когда кто-то да закинет какой-то стиль в глобальный.
    Или появляются кросс-раздельные css'ы.
    Один раз произошло наложение стилей, где ошибочный стиль в глобальном.css правился в мелких.css.

    Ну и спасает уникальныость классов: li.list {...} -> li.user_offers {...}
    В итоге, чистка, не идеально, но упростилась.
    И вместо одного здоровенного файла появилось 2-3 мелких на раздел.


  1. Fragster
    27.11.2019 19:00

    Вот неплохой вариант: www.purgecss.com


  1. mSnus
    28.11.2019 00:36

    Сразу захотелось написать тулзу на JS (плагина к Хрому, например), которой можно в полу-автоматическом режиме собрать "карту состояний" сайта — вот страница, вот она же в состоянии "я навелся на кнопку", вот она в состоянии "всплыло модальное окно". А дальше уже анализировать суммарный CSS всех этих состояний. Ну и грабить корованы, конечно.


    Но наверняка этот велосипед уже кто-то изобрёл, поэтому сначала надо дождаться второй части статьи.


    1. TimsTims
      28.11.2019 01:02

      вот она в состоянии "всплыло модальное окно"

      Этого будет мало, окажется, что ещё надо эмулировать разный размер экрана, на разных версиях браузера, и при разных входящих данных, и что вообще вам надо научить скрипт понимать Js, и понимать его логику. На выходе у вас получится новый браузер.


  1. NikolasPushkin
    28.11.2019 12:37

    Спасибо за статью, эта проблема очень актуальна, по поводу редизайна — часто и густо в моей практике когда сайт переходит на новый дизайн постепенно и это постепенное обновление заставляет держать стили версии 1, версии 1.1, версии 1.2 и и.д. и нет этому конца у постоянно растущего сервиса.


  1. ru_vds Автор
    28.11.2019 12:38

    Опубликовали 2 часть статьи.