Всем привет! В этой статье я бы поделился тем, что обнаружил, копаясь под кожей библиотеки Emotion-js.

Мотивация

Я довольно долго исследовал CSS-in-js и его преимущества, так как хотел включить его в один из моих проектов, над которыми я работаю в Postman. Поэтому я попытался просмотреть некоторые из лучших библиотек на рынке, чтобы проверить, какая из них подходит для моей цели. Чтобы измерить их с точки зрения операций времени выполнения, компромиссов перерисовки браузера и накладных расходов на javascript, я попытался понять, как эти библиотеки работают под капотом.

Для библиотек типа styled-components доступно достаточно контента, но я не смог найти много информации об эмоциях. В этой статье я хочу поделиться этими знаниями, собранными с помощью инструментов разработчика Chrome, анализа кодовой базы и немного поболтать с сообществом эмоций.js (они очень быстро отвечают) 🙂.

Итак, приступим 🎉

Я поговорил с Andarist (одним из активных разработчиков эмоций) и Kyle (создателем библиотеки), чтобы узнать, как эмоция выполняет основную магию.

У эмоции есть два способа создания определений стиля:

  1. Статически - определение стиля может быть вычислено заранее. Пример: - где стили не меняются в ответ на некоторую опору
  2. Динамически, где определение стиля вычисляется на клиенте.

Объект стиля состоит из двух свойств - имя здесь фактически вычисляется путем хеширования строки стилей, а другое свойство - styles, которое получается как простая строка стилей.

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

Примечание. - В Emotion все стили, которые мы пишем в наших шаблонных литералах (styled. ‹element› и css), или в конечном итоге станут объектами определения стиля. Они определяют, какие стили следует применять, будь то поле, преобразование, цвет или любое другое свойство.

Это означает, что если у нас есть стили, написанные с использованием эмоций вроде этого:

преобразуется во что-то вроде: -

▶ ️ styled API будет хранить определения, и, если используются реквизиты, сериализует эти определения с любыми полученными реквизитами. Все они будут вычислены для объекта, подобного приведенному выше.

▶ ️ css API не принимает реквизиты, поэтому все эти стили будут быстро вычисляться и сохраняться как объекты. Вы можете составлять стили, которые будут просто объединять определения по порядку и выводить другой объект стиля, как указано выше.

Следующий шаг: создание className

  • Теперь имена классов создаются, когда у нас есть объекты определения стиля. Это делается путем создания Правил стилей, которые используют имя класса в качестве селектора, а также соответствующих стилей для контента, и внедрения их с помощью API-интерфейсов CSSOM.
  • Используя приведенный выше объект определения стиля в качестве примера, имя класса правила стиля будет вычисляться путем предварительного добавления ключа кэша к объекту object.name, а содержимым правила будет object.styles.
  • Когда правило стиля готово к вставке, запускается идемпотентный побочный эффект **, при котором кеш проверяется, чтобы увидеть, существует ли этот хэш уже. Поскольку хэш вычисляется из строкового значения применяемых стилей, это означает, что Emotion может проверять уникальность стиля только по хеш-значению.

Поскольку создание / разрешение стилей идемпотентно по своей природе, эмоции могут легко вызвать побочный эффект при рендеринге реакции.

Итак, если Emotion обнаруживает хэш, который уже существует в кеше, Emotion откажется от вставки стилей, потому что они уже существуют.

Что мне нравилось в эмоциях? 🤔

В отличие от некоторых известных библиотек CSS-in-js, таких как стилизованные компоненты, Emotion отслеживает, совпадают ли стили, представленные ранее, и новые стили (путем проверки через кеш), поэтому он пропускает вышеуказанные накладные расходы и легко сбрасывает, не создавая любые новые стили и хэши имен вычислительных классов.

Предостережения

  1. Правила стиля хэшей Emotion основаны на определении, а не на компоненте. Если у вас есть заголовок, который получает реквизиты для определения его цвета, один может отобразить зеленый заголовок, а второй - ярко-розовый. У них обоих будут разные имена классов, даже если они имеют один и тот же заголовок, потому что определение style преобразуется в другую строку.
  2. При написании определений стилей & - имя класса - вычисляется лениво во время выполнения на клиенте.
  3. По этой причине одноуровневые селекторы (& + &) могут быть небезопасными или, по крайней мере, неожиданными. Потому что вы не можете гарантировать, что & (который основан на определении стиля, а не на компоненте) будет ссылаться на правильное имя класса.

Анализ производительности во время выполнения

Я попытался создать маленькую кнопку с помощью эмоций и проанализировал перфомансы с помощью инструментов разработчика Chrome.

Стоимость javascript

Emotion выполняет тот же подход, что и стилизованные компоненты, с простой настройкой: -

👉 Перед повторным вычислением имени хеш-класса проверьте, существует ли хеш в кеше.

👉 Если хеш не существует, пересчитайте хеш и введите стили, в противном случае пропустите вышеупомянутые шаги

Случай 1. Когда в кеше уже есть хеш имени класса

В этом случае эмоция не вводит никаких новых стилей в DOM и, следовательно, завершает свою работу примерно за 0,13 мс времени.

Случай 2. Когда кеш пуст

В этом случае эмоция повторно вычисляет имя класса хеширования с использованием алгоритма хеширования шума, сериализует строку стилей и вводит результат в DOM. Это занимает примерно 0,30 мс времени.

Краска над головой

Как и в случае со стилизованными компонентами, эмоции также не добавляют побочных эффектов на стороне браузера.

Часто задаваемые вопросы по Andarist

Вот некоторые из вопросов, которые я задал andarist о представлении эмоций и их работе:

Благодарственное письмо 🙂

Спасибо за прочтение! Надеюсь, это помогло бы вам узнать, как работают эмоции и их показатели эффективности. Пожалуйста, хлопайте в ладоши, если вы сочли это полезным 🙂

Если вы хотите узнать больше о любых других библиотеках, таких как стилизованные компоненты или о любых других вещах, я с удовольствием подключусь!