Создание серверных компонентов

Fresh — это современный фреймворк для разработки веб-приложений на базе Deno, ориентированный на производительность и минимизацию JavaScript на клиенте. Одним из ключевых его элементов являются серверные компоненты, позволяющие рендерить страницы на сервере и передавать готовый HTML на клиент без лишних загрузок скриптов.

Основы серверных компонентов

Серверный компонент в Fresh — это функция, которая возвращает JSX или HTML. Такие компоненты исполняются только на сервере, что делает их крайне эффективными для начальной загрузки страницы и SEO.

Пример базового серверного компонента:

export default function Greeting({ name }) {
  return (
    <div>
      <h1>Привет, {name}!</h1>
      <p>Это серверный компонент Fresh.</p>
    </div>
  );
}

Ключевые особенности:

  • Исполнение на сервере: компонент не содержит клиентского JavaScript.
  • Прямой рендеринг в HTML: браузер получает готовую разметку.
  • Стабильность данных: серверные компоненты используют данные напрямую с сервера, что уменьшает необходимость в асинхронной загрузке на клиенте.

Маршрутизация и серверные компоненты

Fresh использует файловую маршрутизацию. Любой файл .tsx или .ts в папке routes автоматически становится маршрутом. Серверные компоненты здесь используются для рендеринга страниц.

Пример маршрута:

// routes/index.tsx
import Greeting from "../components/Greeting.tsx";

export default function Home() {
  return <Greeting name="Мир" />;
}

Такой компонент рендерится на сервере и возвращает HTML на клиент. Это позволяет строить страницы без необходимости загружать React на фронтенд.

Работа с данными

Серверные компоненты Fresh хорошо интегрируются с внешними API и базами данных. Асинхронные функции внутри компонента позволяют получать данные до рендеринга страницы:

export default async function UsersList() {
  const res = await fetch("https://jsonplaceholder.typicode.com/users");
  const users = await res.json();

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

Преимущества такого подхода:

  • Данные готовы к моменту рендеринга.
  • Нет лишних запросов с клиента.
  • Полная поддержка асинхронного кода без использования состояния на клиенте.

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

Серверные компоненты сами по себе не предназначены для интерактивности. Для динамических элементов Fresh предлагает клиентские компоненты, которые могут использовать React state, обработчики событий и эффекты.

Пример смешанного подхода:

// components/CounterClient.tsx
"use client";

import { useState } from "preact/hooks";

export default function Counter() {
  const [count, setCount] = useState(0);
  return (
    <button onCl ick={() => setCount(count + 1)}>
      Нажато {count} раз
    </button>
  );
}

// routes/index.tsx
import Counter from "../components/CounterClient.tsx";
import Greeting from "../components/Greeting.tsx";

export default function Home() {
  return (
    <>
      <Greeting name="Мир" />
      <Counter />
    </>
  );
}

Серверные компоненты отвечают за рендеринг статической части страницы, а клиентские — за интерактивность. Такой подход минимизирует объем JavaScript на клиенте и ускоряет загрузку страниц.

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

Серверные компоненты в Fresh позволяют:

  • Сокращать размер загружаемых скриптов. Только интерактивные части приложения получают JavaScript.
  • Использовать кэширование на сервере. Можно кэшировать результат рендеринга для часто посещаемых страниц.
  • Ускорять Time to First Byte (TTFB). Готовый HTML отправляется мгновенно, без ожидания загрузки клиентского JavaScript.

Работа с Layout и частями страницы

Fresh поддерживает использование компонентов для общего layout. Серверные компоненты идеально подходят для header, footer и других частей страницы, которые одинаковы для всех маршрутов.

Пример Layout:

// components/Layout.tsx
export default function Layout({ children }) {
  return (
    <div>
      <header>Мой сайт</header>
      <main>{children}</main>
      <footer>© 2025</footer>
    </div>
  );
}

// routes/about.tsx
import Layout from "../components/Layout.tsx";

export default function About() {
  return (
    <Layout>
      <h1>О сайте</h1>
      <p>Информация о проекте.</p>
    </Layout>
  );
}

Использование серверных компонентов для Layout позволяет избежать дублирования кода и улучшает производительность страниц.

Взаимодействие с формами и серверными обработчиками

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

Пример:

export default function Contact() {
  return (
    <form method="POST">
      <input name="email" type="email" placeholder="Email" required />
      <textarea name="message" placeholder="Сообщение" required />
      <button type="submit">Отправить</button>
    </form>
  );
}

Сервер может обрабатывать отправку формы через функции handler, размещенные в файле маршрута, что исключает необходимость отдельного API на клиенте.

Итоговые принципы работы с серверными компонентами Fresh

  • Серверные компоненты рендерятся на сервере и отправляют готовый HTML.
  • Они минимизируют загрузку JavaScript на клиенте.
  • Асинхронные операции выполняются на сервере до рендеринга страницы.
  • Для интерактивных элементов используются клиентские компоненты.
  • Layout и повторяющиеся элементы лучше реализовывать как серверные компоненты для оптимизации.
  • Формы и серверные действия можно полностью обрабатывать на сервере, повышая безопасность и производительность.

Серверные компоненты Fresh создают фундамент для быстрого, легкого и SEO-дружелюбного веб-приложения, сохраняя при этом возможность плавной интеграции интерактивных клиентских элементов.