Битва css-in-js

Битва css-in-js

От автора: мы на сайте HelloFresh постоянно боремся со стилями. Еще год назад стили на нашем сайте были плохими, запутанными, кода было слишком много, как и у множества других компаний. Мы захотели поправить эту ситуацию и нашли новенькую библиотеку css-in-js.js, очень крутая штука.

В итоге мы пришли к Aphrodite, потому что:

крутое название;

ее написали Khan Academy, а значит, они, скорее всего, тоже ее используют.

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

Сейчас, пару месяцев спустя мы решили пересмотреть свой выбор (см. как мы создавали все приложение здесь). Нам нравился наш выбор, но мы хотели посмотреть на что-то новое. К счастью когда мы создали приложение, мы решили добавить некий слой интерфейса между реальными выходными данными в classNames компонента и используемой нами библиотекой. Рефакторинг не вызвал особых затруднений (к счастью).

Среди вариантов были (по крайней мере, из того, что мы нашли):

Aphrodite, все еще мощная штука, да и название крутое.

Glamor, очень нравится API на правилах.

JSS, отличный логотип, хорошее API, можно создавать вложенные стили.

CXS, функциональный CSS, ЧТО!?

Битва

Мы взяли все библиотеки и сравнили их вес, API и производительность.

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

Первый тест был простым:

Конечно, это упрощенная версия, и она не будет работать из-за style-lib. Но этот пример хорошо показывает именно то, как мы тестировали.

Тесты проводились на Macbook Pro с большим объемом памяти и CPU, тесты запускали при помощи Benchmark.js.

Попытка 1

Результаты первого теста:

Как видно, медленным был JSS, очень медленным. Тьяго, один из наших front-end разработчиков завел доработку, о которой можно прочитать здесь. Оказалось, что мы все время писали поверх глобального JSS объекта и не переустанавливали его. Стандартная реализация не такая убогая, как у нас.

К счастью они сделали фикс для нас, и мы смогли создавать новый экземпляр под каждый тест. Новые результаты уже примерно сходились с ожиданиями:

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

Мы запустили тест еще раз, в этот раз с cxs/optimized, библиотекой от CXS, которая должна повысить производительность в браузере.

Мы решили измерять длину строки также на выходе из библиотеки, что будет включать отрисованный HTML и CSS.

Расширяем тест

Конечно, тестировать один класс не составляет труда для любой библиотеки. Поэтому мы пошли дальше и добавили тест, который создает много классов с одинаковыми стилями. И еще один, который создает много классов, но уже с разными стилями (просто padding-left с инкрементом).

В этих тестах мы также измеряли, какая библиотека даст минимальное значение на выходе.

Тест по перегрузке классов

Тест по перегрузке стилей

CXS и Glamor отлично справились со слиянием классов, но в тесте с разными стилями все показали примерно одинаковые результаты. Выделился только CXS.

Все библиотеки не стали сливать классы на верхнем уровне (когда стили одинаковые), посмотреть это можно ниже:

Битва css-in-js

Если рассматривать операции посекундно, JSS без предустановок выигрывает по всем фронтам, а Glamor плохо себя показал с разными стилями. Если бы вы на самом деле использовали JSS с заданной библиотекой, то преимущества у победителя, судя по тесту, минимальны. CXS определенно отличный вариант, но и JSS с предустановками по умолчанию занимает достойное второе место, им удалось достичь хорошей производительности ядра без жестких предустановок.

Победитель: CXS

Размер пакета

Вся сила библиотеки ничего не стоит, если она много весит. Поэтому дальше мы сравнили размеры при запаковке через Webpack. Результаты:

Как видите, JSS – самая быстрая библиотека, но и одна из самых больших. Результаты CXS тоже очень хорошие, разработчики не соврали. Функциональные библиотеки должны иметь небольшой размер. Glamor говорит в файле README, что у них маленький вес, но на самом деле по сравнению с остальными вес не такой уж и маленький.

Победитель: CXS

API

Хорошее время обработки и небольшой вес – это очень важно, но нам также нужно работать с этими библиотеками каждый день. API также очень важный аспект.

Ниже мы покажем, как используются API в упрощенных формах.

Aphrodite

В Aphrodite код очень подробный, и они стараются далеко не отходить от обычного CSS. В API используются слова типа StyleSheet и css. Метод renderStatic отрисовывает CSS в виде строки.

CXS

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

Glamor

API Glamor заимствует отдельные элементы из API CXS и Aphrodite. Также Glamor требует, чтобы HTML возвращался в колбэк-функцию.

JSS

API JSS понять немного сложнее. Он заимствует часть у Aphrodite, а рендеринг CSS больше похож на CXS.

Победитель: CXS

Интеграция с клиентом

Предыдущие тесты брали в расчет только рендеринг кода на сервере. Если вы рендерите CSS на сервере, вам не нужно делать те же самые операции в клиенте. Так какая из библиотек лучше всего с этим справляется? Вычислить это с помощью тестов довольно сложно. При переходе с сервера в клиент нам нужно было бы написать что-то заумное на PhantomJS. Мы подумали, что объяснить и сравнить, что каждая библиотека делает, будет намного лучше.

Aphrodite и Glamor осторожно генерируются заново перед разворачиванием в клиенте. Glamor хорошо объясняет весь процесс здесь. Однако ни CXS ни JSS не думают о том, что уже было отрисовано на сервере. В инструкции к CXS говорится, к примеру, что нужно просто удалить тег style, который попал туда с сервера после того, как клиент сгенерирует весь CSS.

Победитель: Glamor

Заключение

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

Я считаю, что явного победителя нет. У нас есть реальная проблема с повторной генерацией. Как правило, стилей у нас много, и нам приходится повторно их генерировать для одной страницы, что довольно расточительно. Я создал заявку на доработку в репозитории JSS на эту тему, и мне дали пару хороших советов. Надеемся, что эта битва будет иметь хоть какую-то пользу!

И да, не забудьте посмотреть исходники тестов! Не стесняйтесь добавлять свои css-in-js библиотеки!

Редакция: Pepijn Senders

Источник: //engineering.hellofresh.com/

Редакция: Команда webformyself.

Метки:

Похожие статьи:

Комментарии Вконтакте: