Первый взгляд на Solid.js
Привет, на связи Antihype JS. Сегодня рассмотрим набирающий популярность frontend фреймворк - Solid. Сравним его с React, рассмотрим плюсы и минусы.
Solid имеет похожее на React API. Он также использует JSX для наших компонентов и построен на концепции однонаправленного потока данных.
Однако, Solid не использует абстракции по типу VDOM для детекта изменений и внесения их в DOM. Фреймворк построен вокруг собственной системы реактивности (сигналы) и компилятора. За счет этого, Solid может работать напрямую с DOM, показывать значительно лучшую производительность и низкое потребление памяти.
Пример простого компонента на Solid:
Ничего не напоминает?
Реактивность
Сигнал и функция для изменения его значения создаются с помощью createSignal:
Обратите внимание, что count является не значением, а функцией.
При этом, создавать сигналы можно в любом месте вашей программы. В отличие от хуков в React, которые работают только в контексте компонентов.
Для отслеживания значения сигнала и создания сайд-эффектов используется createEffect:
Эффект автоматически подписывается на изменения используемых внутри сигналов. Больше никаких массивов зависимостей.
Производный сигнал создается с помощью createMemo:
Сигналы, созданные с помощью memo, также автоматически отслеживают свои зависимости. Производные сигналы кэшируются и обновляются при изменении значения любого из сигналов зависимостей.
Жизненный цикл компонента
В Solid наши компоненты вызываются только один раз, а затем всю работу по обновлению DOM делает система реактивности.
Для подписки на событие монтирования компонента в DOM используется функция onMount, для анмаунта - функция onCleanup.
Больше никаких ререндеров компонентов.
Компилятор JSX
Solid использует свой компилятор JSX шаблонов для работы напрямую с реальным DOM.
После компиляции шаблоны превращаются в оптимизированный JS код для точечного обновления элементов.
Например, наш компонент:
после компиляции превращается в следующий JS код:
Функция создает DOM элементы, привязывает обработчики событий, делает подписку на обновления нужных узлов.
Подписка создается внутри функции insert:
Если запустить наш проект в браузере, то мы увидим, что при изменении значения счетчика обновляется только наша кнопка - parent:
Чтобы ваш код максимально эффективно работал с DOM, библиотека предлагает следующий набор встроенных компонентов для работы с условиями и списками:
<Show />
when - сигнал предикат
fallback - работает как ветка else, контент будет показан, если сигнал joinedAntihypeJS вернет значение false
<For />
При изменении массива subscribers <For> обновляет или перемещает узлы в DOM, а не создает их заново. Для работы необходимо передать только сигнал массив в пропс each.
Вместо передачи компонента в children <For />, мы передаем колбэк. Первый аргумент - элемент массива, второй - индекс.
Индекс является сигналом по умолчанию. Это сделано для оптимизации при изменении порядка элементов в массиве. Элементы DOM будут поменяны местами и не будут удаляться и создаваться заново.
Bundle size
Воспользуемся сервисом bundlejs для сравнения размера библиотек Solid и React.
react + react-dom: 138kb в минифицированном виде и 44kb в gzip
solid-js: 19kb в минифицированном виде и 7kb в gzip
Performance
Постоянная ссылка на это сравнение на сайте: js-framework-benchmark. Выбрали нативные Solid и React, а также их комбинации с различными стейтменеджерами.
Время рендеринга при манипуляциях со строками таблицы:
Метрики, снятые при старте приложения:
Потребление памяти:
Как видно, производительность Solid в этом бенчмарке сравнима с реализацией на нативном JS.
Экосистема
К сожалению, на текущий момент Solid не может похвастаться такой богатой экосистемой, как React. На сайте библиотеки собраны официальные пакеты и пакеты от сообщества. Уже существуют биндинги для разных стейтменеджеров, роутеры и порты дизайн систем.
Заключение
Использовать Solid в в продакшен проекте или нет - решать исключительно вам. Но наша редакция советует не проходить мимо этого инструмента.
Если вам понравился контент и вы интересуетесь фронтенд-разработкой, то подписывайтесь на наш телеграм-канал.