Хороший вопрос для собеседований фронтенд-разработчиков по мнению Алекса Рассела: «почему CSS-in-JS плох для производительности?» Я заметил, что в сообществе последнее время чаще стали обсуждать эту тему.
В своё время CSS-in-JS стал решением для фреймворков (прежде всего для React), где нужен был способ стилизации компонентов в JS с изоляцией стилей, динамикой на основе состояния, темизацией и различными оптимизациями.
Всё это обеспечивается благодаря описанию стилей в виде объектов или шаблонных строк в JS-коде. Стили становятся частью компонентов и связаны с ними. Вместе с преимуществами такого подхода выявились недостатки.
Так как стили хранятся в JS, требуется движок, который преобразует JS-представление в итоговую строку CSS и передаст браузеру. С кодом компонентов и логикой приложения нужно поставлять код движка, что увеличивает бандл.
Чем больше бандл, тем дольше он загружается и обрабатывается браузером. Особенно это заметно на нестабильных мобильных сетях и слабых устройствах. Замедляется отрисовка приложения, ухудшается отзывчивость.
Движку требуется время для обработки стилей и генерации хэш-классов. Это загружает основной поток работой с DOM и CSSOM, создавая конкуренцию с задачами по построению интерфейса и обработке пользовательского ввода.
У браузера нет шансов применить оптимизации, заранее загрузить и обработать стили, расставить приоритеты загрузки, кэшировать, потому что стили не видны для HTML-парсера и сканера предварительной загрузки.
Джоно Олдерсон отмечает, что хэш-классы, которые генерируют CSS-in-JS движки, ломают кэш, делают селекторы для аналитики и E2E тестов нестабильными, усложняют читаемость разметки и затрудняют повторное использование стилей.
Главный контрибьютор популярного CSS-in-JS решения Styled Components объявил о прекращении разработки, назвав среди причин уход сообщества от CSS-in-JS подхода и прекращение использования его на собственных проектах.
Если на проекте используется CSS-in-JS, рассмотрите возможность перехода на zero runtime решения. Они предлагают аналогичные возможности и синтаксис, но генерируют статические стили на этапе сборки проекта, например:
- vanilla-extract
- Panda CSS
- Linaria
- Compiled
Предварительно генерируемые CSS-файлы, подключаемые к странице через
<link rel="stylesheet"> работают лучше. Динамику обеспечат пользовательские свойства, а классы можно сгенерировать на этапе сборки.#css #js #performance