Плюсы и минусы CSS в JS

CSS
Плюсы и минусы CSS в JS

что

CSS-in-JS — это метод, а не конкретная реализация библиотеки. Проще говоря, CSS-in-JS — этоЗапишите примененные стили CSS в файле JavaScript., а не независимо для некоторых.css,.scssилиlessТакие файлы, чтобы вы могли использовать некоторые языковые функции в CSS, такие как объявления модулей, определения переменных, вызовы функций и условные суждения, которые принадлежат JS, чтобы обеспечить гибкие и расширяемые определения стилей. Стоит отметить, что хотя технология CSS-in-JS не очень новая, ее популярность в Китае не очень высока.component-basedРастущая популярность веб-фреймворков (таких как React, Vue и Angular) побуждает разработчиков инкапсулировать стили компонентов CSS в компоненты, чтобыРешите ряд проблем с нативным написанием CSS. Кроме того, в сообществе React наиболее популярен CSS-in-JS, поскольку самому React все равно, как пользователи определяют стили для компонентов, тогда как Vue и Angular имеют собственный набор стилей для фреймворка.

Эта статья поможет вам решить, хотите ли вы использовать CSS-in-JS в своем проекте, проанализировав преимущества технологии CSS-in-JS и некоторые ее проблемы.

различные реализации

Существует множество библиотек, реализующих CSS-in-JS,Согласно статистикеВ настоящее время насчитывается более 61 вида. Хотя каждая библиотека решает одну и ту же задачу, их реализация и синтаксис сильно различаются. Существует два типа методов реализации: уникальные селекторы CSS и встроенные стили (уникальный селектор VS встроенные стили). Далее мы рассмотрим две репрезентативные реализации, соответствующие этим двум реализациям:styled-componentsа такжеradium.

Styled-components

Styled-componentsЭто должна быть самая популярная библиотека CSS-in-JS, на данный момент количество звездочек на github перевалило за 27 тысяч. Со стилизованными компонентами вы можете использовать ES6.строка шаблона этикеткиГрамматика (шаблоны с тегами) по мере необходимостиstyledКомпонент определяет ряд свойств CSS.Когда код JS компонента анализируется и выполняется, styled-components динамически генерирует селектор CSS и вставляет соответствующий стиль CSS в тег заголовка в виде тега стиля. Динамически генерируемые селекторы CSS имеют небольшое хеш-значение, чтобы обеспечить глобальную уникальность и избежать конфликтов стилей.

CSS-in-JS Playground— это быстрый способ опробовать различные реализации CSS-in-JS на простом примере реализации формы со стилизованными компонентами:

Как видно из приведенного выше примера, styled-components не требует, чтобы вы задавали имя стиля для узла DOM, который необходимо стилизовать.После использования определения строки шаблона тега вы получите стилизованный компонент, который можно использовать прямо в JSX. Затем давайте откроем DevTools и посмотрим на сгенерированный CSS:

Из приведенного выше DevTools мы видим, что стилизованный стиль компонента существует в теге стиля, а имя селектора представляет собой случайную хэш-строку, которая фактически обеспечивает эффект локальной области видимости CSS (стили области видимости), а стили каждого компонента разные.Конфликты будут происходить. В дополнение к styled-components, реализациями, использующими уникальный подход CSS-селекторов, являются:jss,emotion,glamorousЖдать.

Radium

Radium— это библиотека CSS-in-JS с более чем 7,2 тысячами звезд на github, созданная FormidableLabs. Самая большая разница между Radium и styled-components заключается в том, что он генерирует встроенные стили для тегов. Поскольку встроенные стили тегов обрабатывают такие вещи, какmedia queryтак же как:hover,:focus,:activeОчень неудобно ждать стилей, связанных с состоянием браузера, поэтому radius инкапсулирует некоторые стандартные интерфейсы и абстракции для этих стилей.

Давайте еще раз посмотрим на пример радиуса в CSS-in-JS Playground:

Из приведенного выше примера видно, что синтаксис для определения стилей в radius сильно отличается от styled-components, что требует использования атрибута style для добавления соответствующих стилей в DOM. Откройте DevTools, чтобы увидеть CSS, сгенерированный радиусом:

Как видно из результатов проверки DevTools выше, радиум будет генерировать встроенные стили непосредственно внутри тега. Встроенные стили имеют следующие преимущества по сравнению с селектором CSS:

  • Автономные эффекты области локального стиля, никаких дополнительных операций не требуется
  • Специфика встроенного стиля является самой высокой, что позволяет избежать проблем с конфликтом веса.
  • Так как стиль написан непосредственно в HTML, разработчикам очень удобно отлаживать

другие отличия

В дополнение к различиям в сгенерированных стилях CSS и синтаксисе написания, разные реализации CSS-in-JS также реализуют разные функции. За исключением некоторых основных функций, таких как локальная область действия CSS, будут реализованы некоторые из следующих функций. Включено, но не поддерживается. :

  • Автоматически генерировать префикс движка браузера — встроенный префикс поставщика
  • Поддержка извлечения независимых таблиц стилей CSS — извлечение файла css
  • Встроенная поддержка анимации
  • Псевдоклассы - псевдоклассы
  • медиа-запрос — медиа-запрос
  • разное

Чтобы узнать больше о сравнении различных CSS-in-JS, вы можете взглянуть на различные реализации, скомпилированные Микеле Бертоли.Сравнительная таблица.

выгода

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

Локальные стили — стили области видимости

Одна из наиболее критикуемых проблем с CSS заключается в том, что он не имеет локальной области видимости, а все объявленные стили являются глобальными стилями. Другими словами, пока какой-либо элемент на странице соответствует правилу селектора, правило будет применяться, и правила и правила могут накладываться друг на друга (каскадирование). После популярности SPA-приложений эта проблема стала более заметной, потому что для SPA-приложений код стилей всех страниц будет загружаться в одну и ту же среду, и вероятность конфликтов стилей будет сильно увеличена. Из-за существования этой проблемы мы столкнемся со следующими проблемами в ежедневной разработке:

  • Трудно придумать имена для селекторов. Во избежание конфликтов со стилями других элементов на странице, мы должны хорошо подумать при выборе имени селектора, и имя не должно быть слишком расхожим. Например, если вы определяете узел DOM с именем.titleимя стиля, это имя класса конфликтует или будет конфликтовать с другими селекторами на странице, поэтому вы должныруководствоДобавьте некоторый префикс к этому имени класса, например..home-page-titleчтобы избежать этой проблемы.
  • Сложно работать в команде. Когда несколько человек разрабатывают один и тот же проект вместе, особенно когда несколько веток разрабатываются одновременно, имена селекторов, выбранные каждым из них, могут конфликтовать, но эту проблему практически невозможно обнаружить при независимой локальной разработке. Когда все коды объединяются в одну и ту же ветку, возникают некоторые проблемы со стилем.

CSS-in-JS обеспечитавтоматическийФункция локальной области CSS, стили, которые вы определяете для компонента, будут ограничены этим компонентом и не повлияют на стили других компонентов. Различные библиотеки CSS-in-JS могут по-разному реализовывать локальную область видимости, но обычно они ограничивают область действия стилей CSS, создавая уникальные селекторы для стилей компонента. Вот пример кода для упрощенной библиотеки CSS-in-JS, которая генерирует уникальные селекторы:

const css = styleBlock => {
  const className = someHash(styleBlock);
  const styleEl = document.createElement('style');
  styleEl.textContent = `
    .${className} {
      ${styleBlock}
    }
  `;
  document.head.appendChild(styleEl);
  return className;
};
const className = css(`
  color: red;
  padding: 20px;
`); // 'c23j4'

Как видно из приведенного выше кода, реализация CSS-in-JS сгенерирует уникальный селектор CSS в соответствии с заданной строкой стиля, а затем вставит соответствующий стиль в тег стиля в заголовке страницы, который используется by styled-components — аналогичный метод.

Избегайте бесполезного стека стилей CSS - устранение мертвого кода

Студенты, которые разрабатывали масштабные веб-проекты, должны были столкнуться с такой ситуацией: при разработке новых функций или рефакторинге кода, потому что нет разницы между HTML-кодом и стилями CSS.Явное взаимное соответствие, нам трудно определить, какой код стилей CSS полезен, а какой бесполезен в проекте, что приводит к тому, что мы не осмеливаемся легко удалить стили, которые могут быть бесполезными в коде. Таким образом, стили CSS в проекте со временем будут только увеличиваться, а не уменьшаться (append-only stylesheets). Накопление бесполезного кода стилей может вызвать следующие проблемы:

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

Идея CSS-in-JS может очень хорошо решить эту проблему. Давайте сначала посмотрим, что сказал Макс Штойбер, автор styled-components:

"В течение трех лет я оформлял свои веб-приложения без каких-либо файлов .css. Вместо этого я писал весь CSS на JavaScript... Я могу добавлять, изменять и удалять CSS без каких-либо неожиданных последствий. Мои изменения в стиле компонент не повлияет ни на что другое. Если я удаляю компонент, я также удаляю его CSS. Больше никаких таблиц стилей, предназначенных только для добавления!» — Макс Штойбер

Макс Штойбер в основном имеет в виду, что, поскольку CSS-in-JS будет связывать стили и компоненты вместе, когда компонент должен быть удален, просто удалите эти коды напрямую и не беспокойтесь об удаленных кодах стилей.Другие стили компонентов проекта эффект. А поскольку CSS написан на JavaScript, мы также можем использовать явные определения переменных JS, ссылки на модули и другие возможности языка для отслеживания использования стилей, что значительно облегчает внесение изменений или рефакторинг кодов стилей.

Critical CSS

Браузер должен загрузить и проанализировать файл CSS, на который ссылается страница, прежде чем представить нашу страницу пользователю, поэтому ресурс CSS, на который ссылается тег ссылки, блокирует рендеринг. CSS, блокирующий рендеринг, может серьезно повлиять на работу пользователя, если файл CSS очень большой или сетевые условия плохие. В ответ на эту проблему у сообщества есть решение по оптимизации, которое помещает некоторый важный код CSS (критический CSS) непосредственно в тег стиля заголовка, а остальная часть кода CSS загружается асинхронно, чтобы браузер мог напрямую анализировать содержимое. HTML после синтаксического анализа HTML Страница визуализируется. Конкретный метод подобен следующему коду:

<html>
  <head>
    <style>
      /* critical CSS */
    </style>
    <script>asyncLoadCSS("non-critical.css")</script>
  </head>
  <body>
    ...body goes here
  </body>
</html>

Итак, как определить критический CSS? Конечно, чем меньше CSS в теге head, тем лучше, потому что слишком много контента увеличит размер html, поэтому мы обычно ставимМинимальный CSS, который пользователь должен видеть на странице в верхней части страницы, извлекается как критический CSS.. Вот схема:

CSS над сгибом на изображении выше является критическим CSS, потому что он должен быть немедленно показан пользователю. Так как страница отображается на разных устройствах по-разному, соответствующий критический CSS-контент также будет разным.Поэтому извлечение критического CSS-это очень сложный процесс.Хотя в сообществе есть много соответствующих инструментов, эффект неудовлетворительный. CSS-in-JS вполне может поддерживать создание критического CSS. В CSS-in-JS, поскольку CSS привязан к компонентам, их стили CSS будут вставлены в тег стиля страницы только тогда, когда компоненты смонтированы на странице, поэтому легко узнать, какие стили CSS необходимо отправить. клиенту при отображении первого экрана, а с помощью функции Code Splitting инструмента упаковки код, загруженный на страницу, может быть минимизирован для достижения эффекта Critical CSS. Другими словами, CSS-in-JS может избежать повторного запроса на получение других файлов CSS, добавив небольшой объем JS для загрузки. Также некоторые реализации CSS-in-JS (например, стилизованные компоненты) имеют решающее значение для CSS.автоматически поддерживается.

Стиль на основе состояния — стиль на основе состояния

Что мне нравится в CSS-in-JS, так это то, что он может динамически генерировать стили на основе состояния компонента. Для приложений SPA, особенно для некоторых страниц со сложным взаимодействием, стиль страницы обычно меняется в зависимости от состояния компонента. Если вы не используете CSS-in-JS, вам будет сложнее справляться с такими сложными логическими ситуациями. Например, если у вас теперь есть точка на странице, она будет отображать разные цвета в зависимости от состояния.runningзеленый, когдаstopкрасный, когдаreadyвремя желтое. Если вы используете схему модулей CSS, вы можете написать следующий код:

style.cssдокумент

.circle {
  ... circle base styles
}

.healthy {
  composes: circle;
  background-color: green;
}

.stop {
  composes: circle;
  background-color: red;
}

.ready {
  composes: circle;
  background-color: 
}

index.jsдокумент

import React from 'react'
import styles from './style.css'

const styleLookup = {
  healthy: styles.healthy,
  stop: styles.stop,
  ready: styles.ready
}

export default ({ status }) => (
  <div
    className={styleLookup[status]}
  />
)

В style.css мы используем наследование модулей CSS, чтобы разделить стиль базового класса круга между классами CSS в разных состояниях Код выглядит очень избыточным и громоздким. Поскольку CSS-in-JS напрямую записывает стили CSS в файлы JS, повторное использование стилей и логическое суждение очень удобны.Если приведенный выше пример написан в styled-components, он выглядит так:

import styled from 'styled-components'

const circleColorLookup = {
  healthy: 'green',
  stop: 'red',
  ready: 'yellow'
}

export default styled.div`
  ... circle base styles
  background-color: ${({ status }) => circleColorLookup[status]};
`

Напротив, логика styled-components понятнее и лаконичнее: если вам нужно добавить состояние позже, вам нужно только установитьcircleColorLookupХорошо добавить пару ключ-значение, а метод написания модулей CSS требует одновременного изменения файлов style.css и index.js, а код непросто поддерживать и расширять.

Улучшенная упакованная библиотека компонентов

В процессе ежедневной разработки вы можете инкапсулировать некоторые компоненты для использования в разных проектах.Если схема препроцессинга CSS, используемая в стиле вашего компонента, отличается от схемы препроцессинга другого проекта, например, компонент использует меньше, проект Используя модули css, повторное использование компонентов станет очень проблематичным. Однако, если CSS написан на JS, в проекте достаточно сделать простойnpm installВот так, очень удобно.

вред

У всего есть свое хорошее и плохое, и мы можем делать более точные суждения, только если мы понимаем хорошее и плохое.. Теперь поговорим о недостатках CSS-in-JS.

Крутая кривая обучения - Крутая кривая обучения

На самом деле это можно объяснить с двух сторон. Прежде всего, CSS-in-JS предназначен для фреймворков, основанных на компонентах, а это означает, что для изучения CSS-in-JS вам нужно изучить: фреймворки на основе компонентов (такие как React), JavaScript и три навыка CSS. Во-вторых, даже если вы уже используете React, JavaScript и CSS для создания SPA-приложений, вам нужно изучить реализацию CSS-in-JS (например, стилизованные компоненты) и изучить совершенно новый способ мышления о стилях, основанных на компонентах. Когда наша команда впервые начала использовать styled-components, потребовалось некоторое время, чтобы научиться правильно использовать эту библиотеку. Поскольку стоимость обучения относительно высока, внедрение CSS-in-JS в проект может снизить эффективность вашей разработки.

Стоимость выполнения - Стоимость выполнения

Поскольку большинство библиотек CSS-in-JS генерируют CSS динамически. Это имеет два эффекта. Прежде всего, код, который вы отправляете клиенту, будет включать в себя используемый код среды выполнения CSS-in-JS. Эти коды, как правило, не очень малы. Например, размер времени выполнения стилевых компонентов составляет12.42kB min + gzip, если вы хотите, чтобы ваш код, загружаемый в верхней части сгиба, был небольшим, вы должны это учитывать. Во-вторых, большинство реализаций CSS-in-JS динамически генерируют CSS на стороне клиента, что означает снижение производительности. Различные реализации CSS-in-JS имеют разную производительность из-за разных деталей реализации.этот инструментдля просмотра и измерения различий в производительности между реализациями.

Плохая читаемость кода - нечитаемые имена классов

Большинство реализаций CSS-in-JS обеспечивают локальную область видимости CSS, создавая уникальные селекторы CSS. Эти автоматически сгенерированные селекторы сильно уменьшат читабельность кода и окажут определенное влияние на отладку разработчиком.

Нет единого отраслевого стандарта — нет функциональной совместимости

Поскольку CSS-in-JS — это просто техническая идея без стандарта и спецификации, которой единообразно следует сообщество, синтаксис и функции разных реализаций могут сильно различаться. Это означает, что вы не можете быстро переключиться с одной реализации на другую. Например, если вы сначала используете радий в своем проекте, но по мере его роста вы обнаружите, что радий может не подходить для вашего текущего бизнеса, и лучшим решением должны быть стилизованные компоненты. Однако из-за огромной разницы в методах написания вам необходимо вносить новые изменения в код, чтобы перенести код на styled-components. Но отрадно, что некоторые люди сейчас формулируют соответствующие стандарты, и заинтересованные студенты могут взглянутьInteroperable Style Transfer Format.

Личное размышление и резюме

CSS-in-JS имеет свои преимущества и недостатки, поэтому мы должны измерять и выбирать в соответствии с нашей реальной ситуацией, чтобы решить, использовать ли его в наших собственных проектах.Никогда не используйте технологию ради использования технологии. Например, он вам не нужен в следующих случаях:

  • Вы новичок во фронтенд-разработке: из-за крутого уклона в обучении CSS-in-JS учащимся, которые только начинают изучать веб-разработку, не нужно учиться, и они могут чувствовать разочарование.
  • Вы просто хотите сделать несколько статических страниц с простыми функциями: веб-сайт с несложными логическими взаимодействиями не нуждается в использовании CSS-in-JS.
  • Обратите внимание на удобочитаемость имен стилей и удобство отладки: динамически генерируемые селекторы CSS-in-JS сильно влияют на удобочитаемость кода и могут снизить эффективность отладки.

Наоборот, если логика взаимодействия вашего приложения сложна, CSS-in-JS может принести вам большое удобство разработки, и его стоит попробовать тем, кто его не использовал.

использованная литература

Тенденции в области персональных технологий

Статья впервые опубликована вмой личный блог

Добро пожаловать в публичный аккаунтатакующий лукучиться и расти вместе