Философия и принципы проектирования

Preact — это минималистичный и высокопроизводительный фронтенд-фреймворк для разработки пользовательских интерфейсов на JavaScript. Его архитектура вдохновлена React, но Preact создан с акцентом на легковесность и скорость, что делает его оптимальным выбором для проектов с ограниченными ресурсами и высокой нагрузкой. Основная философия Preact строится вокруг трёх принципов: компактность, совместимость и реактивность.

Компактность выражается в минимальном размере ядра — около 3 кБ при сжатии gzip. Это позволяет загружать приложения быстрее и снижает нагрузку на сеть и устройство пользователя. Preact не включает лишние абстракции, оставляя только необходимые механизмы для создания компонентов, управления состоянием и виртуального DOM.

Совместимость достигается благодаря Preact/Compat — пакету, обеспечивающему полную или почти полную совместимость с API React. Это позволяет использовать существующие библиотеки и инструменты из экосистемы React без необходимости переписывать код.

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

Компонентная архитектура

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

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

import { h } from 'preact';
import { useState } from 'preact/hooks';

function Counter() {
    const [count, setCount] = useState(0);
    return (
        <button onCl ick={() => setCount(count + 1)}>
            {count}
        </button>
    );
}

Классовые компоненты наследуются от Component и обладают встроенным состоянием и методами жизненного цикла. Используются реже, но остаются важным инструментом для сложных сценариев.

import { h, Component } from 'preact';

class Counter extends Component {
    state = { count: 0 };

    increment = () => this.setState({ count: this.state.count + 1 });

    render() {
        return (
            <button onCl ick={this.increment}>
                {this.state.count}
            </button>
        );
    }
}

JSX и виртуальный DOM

Preact использует JSX для декларативного описания интерфейса. JSX компилируется в вызовы h(), создающие виртуальные узлы. Виртуальный DOM позволяет Preact обновлять только изменившиеся элементы, снижая нагрузку на браузер и повышая производительность.

Принцип работы диффинга:

  1. Сравниваются предыдущая и новая версии виртуального DOM.
  2. Определяется минимальный набор изменений.
  3. Применяются только необходимые изменения в реальный DOM.

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

Управление состоянием и хуки

Preact предоставляет базовые хуки для управления состоянием и эффектами. Основные из них:

  • useState — для локального состояния компонента.
  • useEffect — для выполнения побочных эффектов после рендера.
  • useRef — для сохранения ссылок на DOM-элементы или значения между рендерами.
  • useMemo и useCallback — для оптимизации производительности.

Хуки позволяют писать чистый функциональный код, минимизируя необходимость использования классовых компонентов.

Работа с событиями и атрибутами

События в Preact обрабатываются так же, как и в React, с использованием camelCase-нотации:

<button onCl ick={handleClick}>Click me</button>

Атрибуты DOM также передаются через JSX, при этом большинство HTML-атрибутов сохраняют свои стандартные имена, за исключением зарезервированных слов, таких как className вместо class.

Роутинг и экосистема

Preact имеет собственный минималистичный роутер — preact-router. Он обеспечивает навигацию по SPA без перезагрузки страницы и интегрируется с компонентами так же, как в React. Роутинг реализован через декларативные компоненты <Router> и <Route> с поддержкой динамических сегментов URL.

Для сложных проектов Preact допускает интеграцию с большинством библиотек из React-экосистемы через preact/compat, включая Redux, React Query, styled-components и другие.

Производительность и оптимизация

Preact оптимизирован для быстрого рендера и низкой нагрузки на память. Основные методы оптимизации:

  • Минимизация размера бандла за счёт отсутствия лишних зависимостей.
  • Использование key при рендере списков для точного сопоставления элементов.
  • Применение хуков useMemo и useCallback для избежания ненужных перерендеров.
  • Возможность серверного рендера через preact-render-to-string для SEO и ускорения первичной загрузки.

Эти механизмы делают Preact подходящим выбором для проектов, где важна скорость и экономия ресурсов.

Интеграция с современными инструментами

Preact легко интегрируется с современными сборщиками и инструментами: Vite, Webpack, Parcel. Использование TypeScript с Preact обеспечивает строгую типизацию компонентов, props и состояния, повышая стабильность и читаемость кода.

Фреймворк поддерживает JSX-превращение через Babel и позволяет оптимизировать бандл с помощью tree-shaking. Это обеспечивает минимальный размер приложения и улучшает время загрузки.

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