Hyperapp использует минималистичный подход к управлению состоянием и виртуальному DOM. Основной задачей компилятора является трансформация декларативного описания интерфейса в эффективные вызовы функций, управляющие деревом DOM. В отличие от крупных фреймворков, Hyperapp избегает тяжелых runtime-слоев, перенося максимум оптимизаций на этап сборки.
Компилятор анализирует JSX-структуры или вызовы
h() и превращает их в чистые функции, которые при
исполнении обновляют DOM напрямую. Это позволяет минимизировать
накладные расходы на виртуальный DOM и реконсиляцию.
Hyperapp использует внутренний минимальный виртуальный DOM, но на этапе сборки компилятор способен:
props),
чтобы пропустить сравнение этих узлов при обновлении.Пример оптимизации:
const list = ["apple", "banana", "orange"];
h("ul", {}, list.map(item => h("li", { key: item }, item)));
Компилятор может преобразовать этот код в предвычисленный массив
виртуальных узлов, если массив list является
статическим, тем самым снижая нагрузку на runtime.
Actions в Hyperapp — это функции, которые изменяют состояние приложения. Компилятор способен:
Пример:
const increment = state => ({ count: state.count + 1 });
const doubleIncrement = state => increment(increment(state));
Компилятор может превратить doubleIncrement в одно
действие:
const doubleIncrement = state => ({ count: state.count + 2 });
Это уменьшает количество вызовов функций и повышает производительность.
Hyperapp поддерживает эффекты и подписки (effects,
subscriptions) для работы с внешними ресурсами. На этапе
сборки компилятор анализирует:
Пример:
const fetchData = () => fetch("/api/data").then(res => res.json());
const load = state => [state, fetchData];
Компилятор может предварительно подготавливать вызов fetch, если URL известен на этапе сборки, и минимизировать runtime-вычисления.
Hyperapp интегрируется с современными сборщиками (Rollup, Webpack, Vite) и полностью поддерживает tree shaking:
h() могут быть исключены, если они
никогда не рендерятся.Пример:
const unusedAction = state => ({ value: 42 });
Если unusedAction не вызывается нигде в приложении, она
автоматически исключается из финального бандла.
Для повторяющихся компонентов компилятор способен:
h() в константы.h() в runtime.Пример:
const buttonTemplate = h("button", { class: "btn" }, "Click me");
На этапе компиляции это может быть преобразовано в статический объект виртуального DOM, который повторно используется без пересоздания.
Благодаря таким подходам:
Эти принципы позволяют Hyperapp оставаться лёгким и быстрым, сохраняя декларативный стиль разработки при высокой эффективности runtime.