Первый взгляд на 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 в в продакшен проекте или нет - решать исключительно вам. Но наша редакция советует не проходить мимо этого инструмента.
Если вам понравился контент и вы интересуетесь фронтенд-разработкой, то подписывайтесь на наш телеграм-канал.
1) чем createSignal в solid отличается от useState в react?
2) как вы планируете пробрасывать эти сторы между компонентами?
3) зачем поддувать комментарии пустыми аккаунтами?
1 - useState это хук
Хуки можно вызвать только внутри компонента, вне мира реакта хуки не работают
При изменении стейта в реакте перерендеривается все дерево ниже, чтобы этого избежать вам надо обмазаться React.memo
В солиде же такой проблемы нет изначально, каждые узлы дома зависят от своих сигналов
2 - props, context, стейтменеджеры (createStore из solid/effector/reatom/storeon/различные tanstack-solid-query/solidapollo)
3 - это наши друзья, а не пустые акки
Но зачем, если есть божественный Vue?
не исключено!
На удивление выглядит не так уж и плохо. Можно даже попробовать, но вряд ли уйдет в продакшн, все таки бизнес любит более устоявшиеся решения. Ну а в эпоху LTE и 5G за размер конечного bundle можно уже не париться))))
Я когда увидел сколько весит приложение банков я порядком так сказать о*уел. Российский Сбер или ВТБ - 530 мегабайт, Карл! Некоторые из этих подопытных умудряются кэша насобирать на 170-800 мегабайт. Боже что вы там кэшируете в таким объемах? Это новый тикток? У меня в каждом тока по одной платежной карте, что там может столько весить?!
По этой же причине держу на телефоне минимум приложений, больше веб версиями пользуюсь.
Про размер бандла и 5G соглашусь :)
Вот фигня с кжшем и правда бесит... Чего там такого может храниться...