Hack Frontend Community

Проблемы использования CSS-in-JS и пути их решения

Что такое CSS-in-JS?

CSS-in-JS — это подход к стилизации компонентов, при котором CSS пишется прямо в JavaScript-файлах, часто с использованием библиотек вроде styled-components, emotion, linaria, stitches и других.

Этот подход даёт ряд плюсов: scoped-стили, динамические стили, изоляция, работа с темами и т.д.

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


Основные проблемы CSS-in-JS и как их решить

Потеря производительности при рендере

Каждый раз, когда компонент рендерится, библиотека может пересоздавать классы или стили. Это особенно критично в больших списках или при частом обновлении UI.

Решение:

  • Используйте статические стили, когда возможно.
  • Оборачивайте компоненты в React.memo / useMemo.
  • Некоторые библиотеки (например, Emotion) имеют css-функции для кэширования.

Увеличение размера бандла

CSS-in-JS библиотеки добавляют свой рантайм в JavaScript-бандл, особенно если используются без оптимизаций.

Решение:

  • Использовать Zero-runtime библиотеки, такие как:
    • vanilla-extract
    • astroturf
    • linaria
  • Или использовать компиляцию во время билда (babel plugin, babel macro, vite plugin, webpack loader).

Проблемы с SSR (Server-Side Rendering)

Если сервер не успевает отрендерить стили, пользователь может увидеть "стиль без стилей" — FOUC (Flash of Unstyled Content).

Решение:

  • Использовать библиотеки с официальной поддержкой SSR (styled-components, emotion) и соответствующую настройку:
    • В Next.js → использовать ServerStyleSheet / extractCritical
  • Добавить отложенный рендер до подгрузки стилей.

Сложность отладки

  • Имена классов превращаются в непонятные хэши.
  • В DevTools сложно найти нужный элемент.

Решение:

  • Использовать babel-plugin-styled-components или @emotion/babel-plugin, которые добавляют названия компонентов к классам.
  • Включать displayName: true в конфигурации библиотеки.

Нет автопрефиксов без конфигурации

Браузерные префиксы могут не применяться автоматически, если библиотека не настроена.

Решение:

  • Убедитесь, что CSS-in-JS библиотека использует autoprefixer или postcss.
  • Используйте babel-plugin или конфигурации Webpack/Vite.

Трудности с тестированием и snapshot

Стили привязываются к компонентам, и это может затруднить unit-тесты или snapshot-снимки.

Решение:

  • Тестируйте компонент отдельно от его стилей.
  • Используйте jest-styled-components или @emotion/jest для корректной работы snapshot'ов.

Зависимость от JS-экосистемы

Если у вас проект на Vue или простой HTML, CSS-in-JS будет избыточным и неуместным.

Решение:

  • Используйте CSS-in-JS только в SPA-приложениях с React.
  • Для других случаев — классический CSS, CSS Modules или PostCSS.

Когда CSS-in-JS — оправдан?

Подходит:

  • Когда нужен scoped CSS без глобального загрязнения.
  • При работе с темами и динамическими стилями.
  • Когда используете component-based архитектуру.

Не подходит:

  • Для маркетинговых сайтов с большим количеством анимаций.
  • Для легковесных landing page, где важен минимальный JS-бандл.

Итог:

CSS-in-JS — мощный инструмент, но не серебряная пуля.
Он требует настройки и понимания, чтобы избежать проблем с производительностью, SSR и отладкой.