Preact/render-to-string

preact-render-to-string — это библиотека, предназначенная для рендеринга компонентов Preact в HTML-строку на стороне сервера. Она играет ключевую роль при создании серверного рендеринга (SSR), позволяя отправлять полностью сформированный HTML на клиент, что улучшает производительность и SEO.

Импортировать библиотеку можно следующим образом:

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

Компоненты Preact создаются привычным образом через функцию h или JSX. render принимает компонент и возвращает строку HTML:

const App = () => <div>Hello, Preact!</div>;
const html = render(<App />);
console.log(html); // <div>Hello, Preact!</div>

Основные возможности

1. Рендеринг функциональных и классовых компонентов

preact-render-to-string поддерживает оба типа компонентов:

// Функциональный компонент
const Functional = () => <p>Функциональный компонент</p>;

// Классовый компонент
class ClassComponent extends Component {
  render() {
    return <p>Классовый компонент</p>;
  }
}

console.log(render(<Functional />));
console.log(render(<ClassComponent />));

2. Рендеринг с пропсами и состоянием

Пропсы передаются обычным образом, но состояние компонента классового типа не обновляется при рендеринге в строку — выполняется только первичный render:

const Greeting = ({ name }) => <h1>Привет, {name}!</h1>;

console.log(render(<Greeting name="Иван" />)); // <h1>Привет, Иван!</h1>

Встраивание атрибутов и событий

При рендеринге в строку обработчики событий не работают, так как HTML строка не поддерживает динамику JavaScript. Атрибуты можно передавать обычным образом:

const Button = () => <button class="btn">Нажми меня</button>;

console.log(render(<Button />)); // <button class="btn">Нажми меня</button>

События типа onClick игнорируются, что является нормой для SSR.


Поддержка фрагментов и вложенных элементов

preact-render-to-string корректно обрабатывает фрагменты (<></>) и сложные иерархии элементов:

const List = () => (
  <>
    <li>Элемент 1</li>
    <li>Элемент 2</li>
  </>
);

console.log(render(<ul><List /></ul>)); // <ul><li>Элемент 1</li><li>Элемент 2</li></ul>

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

Для SSR обычно используется в сочетании с Node.js и серверными фреймворками, такими как Express:

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

const App = () => <div>Серверный Preact</div>;

const server = express();

server.get('/', (req, res) => {
  const html = render(<App />);
  res.send(`
    <!DOCTYPE html>
    <html>
      <head><title>Preact SSR</title></head>
      <body>${html}</body>
    </html>
  `);
});

server.listen(3000);

В результате клиент получает готовый HTML, который можно сразу отобразить.


Особенности и ограничения

  • Состояние компонентов обновляется только при первичном рендеринге. Динамическая логика после рендеринга невозможна.
  • Обработчики событий и refs не активны. Для интерактивности необходимо повторно гидратировать HTML на клиенте.
  • Стили в виде атрибутов (style={{...}}) корректно рендерятся в виде строкового атрибута.

Рендеринг с dangerouslySetInnerHTML

Можно использовать для вставки готового HTML внутрь компонента:

const HtmlContent = ({ html }) => <div dangerouslySetInnerHTML={{ __html: html }} />;

console.log(render(<HtmlContent html="<span>Текст</span>" />)); // <div><span>Текст</span></div>

Это полезно при SSR, когда нужно вставлять уже подготовленные HTML-блоки.


Совместимость с JSX и Babel

preact-render-to-string полностью совместим с JSX. Для трансформации JSX требуется настройка Babel или TypeScript с соответствующими плагинами:

// babel.config.json
{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": [
    ["@babel/plugin-transform-react-jsx", { "pragma": "h" }]
  ]
}

Оптимизация

Для крупных приложений рекомендуется:

  • Минимизировать количество рендеров на сервере.
  • Использовать ленивую загрузку компонентов (lazy) совместно с SSR.
  • Компоненты без состояния и побочных эффектов рендерятся быстрее.

preact-render-to-string предоставляет эффективный способ создания быстрых и SEO-дружественных серверных страниц, интегрируясь с существующей экосистемой Preact и JavaScript.