SolidJS построен на принципе тонкой реактивности (fine-grained reactivity), при котором обновления происходят не на уровне виртуального DOM, а на уровне отдельных реактивных выражений. Такой подход позволяет минимизировать лишние пересчёты и обеспечивает предсказуемую производительность даже при сложных интерфейсах.
Основой реактивной модели являются сигналы (signals) — минимальные реактивные единицы состояния. Изменение сигнала приводит к точечному обновлению только тех вычислений, которые напрямую от него зависят.
import { createSignal } from "solid-js";
const [count, setCount] = createSignal(0);
setCount(count() + 1);
Сигнал представляет собой функцию-геттер и отдельную функцию-сеттер, что устраняет необходимость в промежуточных слоях синхронизации состояния.
Реактивные вычисления в SolidJS реализуются через эффекты (createEffect). Эффект автоматически отслеживает зависимости и повторно выполняется при изменении связанных сигналов.
import { createSignal, createEffect } from "solid-js";
const [name, setName] = createSignal("Solid");
createEffect(() => {
console.log("Имя изменилось:", name());
});
Механизм отслеживания зависимостей работает на этапе выполнения: функция эффекта регистрирует все сигналы, которые были прочитаны, и подписывается на их изменения.
Ключевая особенность заключается в отсутствии виртуального дерева компонентов: обновляется только конкретная функция, зависящая от изменённого состояния.
Компоненты SolidJS представляют собой обычные функции, возвращающие JSX. При этом JSX компилируется в высоко оптимизированные вызовы DOM без промежуточного представления.
function Counter() {
const [count, setCount] = createSignal(0);
return (
<button onCl ick={() => setCount(count() + 1)}>
{count()}
</button>
);
}
Каждое выражение в JSX компилируется в отдельную реактивную привязку, что обеспечивает точечные обновления без перерисовки всей функции компонента.
В отличие от React-подобных библиотек, SolidJS не использует виртуальный DOM как промежуточный слой. Вместо этого применяется компиляция реактивных выражений в прямые DOM-операции.
Это приводит к следующим характеристикам:
Помимо createEffect, используется набор специализированных реактивных примитивов:
import { createSignal, createMemo } from "solid-js";
const [count, setCount] = createSignal(1);
const doubled = createMemo(() => count() * 2);
Мемоизация позволяет избегать повторных вычислений, если зависимости не изменились.
import { createResource } from "solid-js";
const fetchUser = async (id) =>
(await fetch(`/api/user/${id}`)).json();
const [user] = createResource(() => 1, fetchUser);
Resource автоматически управляет состояниями загрузки, успеха и ошибки, интегрируясь в реактивную систему.
Жизненный цикл компонентов в SolidJS минималистичен и основан на реактивных хуках.
import { onMount, onCleanup } from "solid-js";
function Example() {
onMount(() => {
console.log("Компонент смонтирован");
});
onCleanup(() => {
console.log("Очистка перед удалением");
});
return <div />;
}
Отсутствие классов и сложной системы хуков делает модель жизненного цикла предсказуемой и локализованной внутри компонента.
SolidJS использует специализированные компоненты управления потоком:
import { Show } from "solid-js";
<Show when={count() > 0} fallback={<div>Пусто</div>}>
<div>Есть данные</div>
</Show>
import { For } from "solid-js";
<For each={items()}>
{(item) => <div>{item}</div>}
</For>
Эти конструкции позволяют избегать ручных проверок и повышают декларативность кода.
Помимо сигналов, применяется модель stores, обеспечивающая глубоко реактивные структуры данных.
import { createStore } from "solid-js/store";
const [state, setState] = createStore({
user: { name: "Alex", age: 25 }
});
setState("user", "age", 26);
Stores поддерживают иммутабельные обновления с возможностью точечного изменения вложенных свойств без пересоздания всего объекта.
SolidJS активно использует компиляцию JSX. На этапе сборки:
Такой подход переносит часть логики из runtime в build-time, снижая нагрузку на браузер.
Асинхронность интегрируется через ресурсы, которые автоматически связываются с реактивными зависимостями.
Изменение сигнала может автоматически перезапускать загрузку данных, формируя реактивный поток:
При увеличении сложности приложения SolidJS сохраняет предсказуемую модель благодаря отсутствию глобального диффинга. Состояние распределяется локально, а реактивные зависимости формируются динамически.
Основные принципы масштабирования:
SolidJS может взаимодействовать с внешними библиотеками через прямой доступ к DOM-узлам и эффектам. Это позволяет интегрировать его в существующие приложения без полной миграции.
Реактивная система остаётся изолированной от внешнего кода, что предотвращает конфликт моделей состояния.