Интеграция в существующие проекты

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


Замена React на Preact

Для большинства проектов с React возможна полная замена через alias в сборщике модулей, например, Webpack или Vite. Это позволяет использовать Preact без изменения существующего кода компонентов.

Пример конфигурации для Webpack:

resolve: {
  alias: {
    'react': 'preact/compat',
    'react-dom/test-utils': 'preact/test-utils',
    'react-dom': 'preact/compat',
    'react/jsx-runtime': 'preact/jsx-runtime'
  }
}
  • preact/compat обеспечивает совместимость с большинством библиотек React.
  • Важно учитывать, что некоторые специфичные для React API (например, unstable_ функции) могут быть недоступны.

Для Vite используется плагин @preact/preset-vite, который автоматически подставляет необходимые алиасы:

import { defineConfig } from 'vite';
import preact from '@preact/preset-vite';

export default defineConfig({
  plugins: [preact()]
});

Инкрементная интеграция

Preact позволяет использовать инкрементальный подход: внедрять его в отдельные части приложения, оставляя остальной код на React. Это полезно для крупных проектов с большим количеством компонентов.

Шаги инкрементной интеграции:

  1. Выделить отдельный модуль или страницу.
  2. Настроить локальный alias на preact/compat только для выбранного модуля.
  3. Проверить совместимость сторонних библиотек, использующих React напрямую.

Такой подход снижает риск ошибок и позволяет оценить производительность перед полной миграцией.


Встраивание Preact в проект с другими фреймворками

Preact хорошо сочетается с серверными рендерерами и статическими генераторами, например, Next.js, Express или даже PHP-шаблонами, через клиентский рендеринг:

import { h, render } from 'preact';
import App from './App';

const rootElement = document.getElementById('root');
render(<App />, rootElement);
  • h — функция для создания элементов Preact.
  • render — метод, который монтирует компонент в DOM.

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


Оптимизация размера бандла

Главное преимущество Preact — малый размер. Даже при полной замене React на Preact можно сократить бандл в 3–4 раза. Для оптимизации важно:

  • Использовать только нужные модули Preact (preact, preact/hooks, preact/compat).
  • Подключать сторонние библиотеки через Preact-совместимые версии.
  • Включать tree-shaking и минификацию в сборщике.

Пример оптимизации с Vite:

build: {
  minify: 'esbuild',
  rollupOptions: {
    treeshake: true
  }
}

Использование хуков и состояния

Preact поддерживает все основные хуки React: useState, useEffect, useRef, useMemo, useCallback. Их поведение практически идентично, что облегчает миграцию существующих компонентов.

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

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const timer = setInterval(() => setCount(c => c + 1), 1000);
    return () => clearInterval(timer);
  }, []);

  return <div>Счетчик: {count}</div>;
}

Особенности хуков в Preact:

  • useEffect и useLayoutEffect работают аналогично React.
  • useRef создаёт ссылку на DOM-элемент, но компонентные refs также совместимы с preact/compat.

Совместимость со сторонними библиотеками

Большинство React-библиотек работают через preact/compat, однако есть исключения:

  • Библиотеки, напрямую завязанные на внутренние API React (react-test-renderer, некоторые версии React Router) могут требовать патчей.
  • Компоненты с contextType без использования hooks иногда вызывают несовместимость.
  • При использовании Redux или MobX необходимо подключать preact/compat для Provider и connect.

Серверный рендеринг

Preact поддерживает серверный рендеринг через preact-render-to-string. Это позволяет генерировать HTML на сервере с последующей гидратацией на клиенте:

import { h } from 'preact';
import renderToString from 'preact-render-to-string';
import App from './App';

const html = renderToString(<App />);

Гидратация:

import { render } from 'preact';
render(<App />, document.getElementById('root'));
  • Серверный рендеринг сокращает время до первого отображения.
  • Поддерживает оптимизацию SEO и социального шаринга.

Совместная работа с существующим CSS и состояниями

Preact не накладывает ограничений на стилизацию и управление состоянием:

  • CSS и CSS-in-JS работают без изменений.
  • Сторонние state-менеджеры (Redux, Zustand, MobX) полностью совместимы через preact/compat.
  • В проектах с глобальными состояниями можно плавно переключать отдельные компоненты на Preact.

Практические рекомендации

  • Начинать с локальных страниц или виджетов, чтобы проверить совместимость.
  • Использовать preact/compat для работы с библиотеками React.
  • Проверять bundle size после замены для оценки эффекта.
  • Прогонять тесты — Preact полностью поддерживает Jest и Testing Library через alias.

Интеграция Preact позволяет уменьшить нагрузку на клиент, ускорить рендер и поддерживать существующую архитектуру React с минимальными изменениями кода.