Концепции серверного рендеринга

Серверный рендеринг (SSR, Server-Side Rendering) — это процесс генерации HTML-кода на сервере вместо браузера. В контексте Preact, SSR позволяет улучшить производительность, ускорить первую отрисовку страницы и повысить SEO-оптимизацию. Preact изначально ориентирован на легковесность, поэтому SSR реализуется через отдельные модули и API, минимизируя накладные расходы.

Рендеринг компонентов на сервере

Для серверного рендеринга Preact предоставляет функцию renderToString из пакета preact-render-to-string. Она принимает дерево компонентов Preact и возвращает строку с готовым HTML.

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

function App() {
  return <div>Привет, Preact SSR!</div>;
}

const html = renderToString(<App />);
console.log(html); // <div>Привет, Preact SSR!</div>

Ключевой момент: renderToString работает синхронно, генерируя статический HTML без выполнения эффектов, завязанных на браузер, таких как useEffect.

Различие между useEffect и useLayoutEffect при SSR

При рендеринге на сервере важно понимать, что хуки useEffect и useLayoutEffect не вызываются, так как сервер не имеет DOM. Для инициализации состояния на сервере следует использовать useState и передавать необходимые данные через пропсы или контекст.

import { useState } from 'preact/hooks';

function Counter({ initial }) {
  const [count] = useState(initial);
  return <span>{count}</span>;
}

Интеграция с серверными фреймворками

SSR в Preact часто используется вместе с Node.js-фреймворками, такими как Express или Fastify. Простейший пример интеграции с Express:

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

const server = express();

server.get('*', (req, res) => {
  const html = renderToString(<App />);
  res.send(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>Preact SSR</title>
      </head>
      <body>
        <div id="root">${html}</div>
        <script src="/bundle.js"></script>
      </body>
    </html>
  `);
});

server.listen(3000);

Гидратация на клиенте

После генерации HTML на сервере необходимо «оживить» интерфейс на клиенте, чтобы компоненты стали интерактивными. Для этого используется функция hydrate из preact.

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

hydrate(<App />, document.getElementById('root'));

Особенность: hydrate связывает уже существующий HTML с Preact-компонентами без перерисовки всего дерева, что ускоряет загрузку страницы.

Передача данных с сервера на клиент

Для динамических приложений данные, полученные на сервере, можно внедрять прямо в HTML через скрипты:

const data = { user: 'Alice' };
const html = renderToString(<App initialData={data} />);
res.send(`
  <div id="root">${html}</div>
  <script>window.__INITIAL_DATA__ = ${JSON.stringify(data)};</script>
  <script src="/bundle.js"></script>
`);

На клиенте данные извлекаются и используются для гидратации состояния:

hydrate(<App initialData={window.__INITIAL_DATA__} />, document.getElementById('root'));

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

  1. Минимизация размеров HTML — Preact уже генерирует компактный HTML, но лишние пробелы и комментарии можно дополнительно удалять.
  2. Кэширование результатов рендеринга — часто используемые страницы можно кешировать на сервере.
  3. Использование ленивой загрузки компонентовpreact/compat позволяет применять динамический импорт и разделять код на чанки.
  4. Избегание тяжелых вычислений в renderToString — серверный рендеринг должен быть максимально легким, чтобы не блокировать поток запросов.

Различия SSR в Preact и React

Preact, в отличие от React, имеет меньший API и отсутствует встроенная поддержка некоторых сложных функций вроде Suspense на сервере. Поэтому подход к рендерингу компонентов и гидратации немного отличается, но базовые принципы остаются схожими:

  • renderToString → генерация HTML на сервере
  • hydrate → интерактивность на клиенте
  • Передача данных через пропсы или глобальные объекты

Поддержка маршрутизации

Для SSR с маршрутизацией используется пакет preact-router. На сервере важно рендерить компоненты, соответствующие текущему маршруту:

import { Router } from 'preact-router';
import Home from './Home';
import About from './About';

function App({ url }) {
  return (
    <Router url={url}>
      <Home path="/" />
      <About path="/about" />
    </Router>
  );
}

На сервере url передается из запроса, чтобы отрендерить корректный компонент.


Серверный рендеринг в Preact позволяет создавать быстрые, SEO-дружественные приложения с минимальным весом. Важнейшие аспекты — корректная работа хуков, передача данных с сервера, гидратация на клиенте и оптимизация производительности. Сочетание этих подходов делает Preact мощным инструментом для создания современных веб-приложений с SSR.