Группировка маршрутов

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

Fresh часто применяется в сочетании с серверным рендерингом (SSR), где сервер генерирует HTML на основе текущего запроса, а клиент получает готовый контент без необходимости дополнительных запросов к API для первичной загрузки страницы. Это уменьшает время до первого отображения (Time To First Paint) и повышает производительность приложений.


Архитектура Fresh

Архитектура Fresh строится вокруг нескольких ключевых компонентов:

  1. Маршруты (Routes) Каждый маршрут соответствует определённому URL и отвечает за генерацию HTML для этого URL. В отличие от традиционных SPA, где клиент скачивает один большой бандл и управляет маршрутизацией, Fresh создаёт маршруты как отдельные сущности на сервере.

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

  3. Автоматическая оптимизация Fresh автоматически разделяет код на чанки, подгружая только то, что необходимо для конкретной страницы. Это снижает объём JavaScript на клиенте и ускоряет загрузку.


Организация маршрутов

В Fresh маршруты организуются по файловой структуре проекта. Каждый файл в папке routes соответствует конкретному пути. Пример структуры:

routes/
├── index.js
├── about.js
├── blog/
│   ├── index.js
│   └── [id].js
  • index.js отвечает за корневой путь /.
  • about.js — за путь /about.
  • Папка blog содержит вложенные маршруты, где [id].js обозначает динамический сегмент URL.

Динамические маршруты автоматически получают параметр id, который можно использовать для генерации страницы, например, загрузки конкретной статьи из базы данных.


Рендеринг и передача данных

Fresh позволяет передавать данные в компонент маршрута через функцию handler или getData. Основная идея — сервер подготавливает все данные до отправки HTML клиенту. Пример:

export async function handler(req, ctx) {
    const postId = ctx.params.id;
    const post = await fetchPostFromDB(postId);
    return ctx.render({ post });
}
  • ctx.params.id — параметр динамического маршрута.
  • ctx.render — функция, которая рендерит компонент с переданными данными.

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


Вложенные маршруты и группировка

Для крупных приложений маршруты можно группировать по функциональным зонам, создавая вложенные папки. Например:

routes/
├── dashboard/
│   ├── index.js
│   ├── settings.js
│   └── users/
│       ├── index.js
│       └── [userId].js
  • /dashboard — главная панель.
  • /dashboard/settings — настройки пользователя.
  • /dashboard/users/[userId] — профиль конкретного пользователя.

Группировка маршрутов упрощает поддержку кода, обеспечивает логическую структуру проекта и позволяет применять общие middleware или layout для группы маршрутов.


Middleware и обработка запросов

Fresh поддерживает middleware на уровне маршрутов и групп маршрутов. Middleware выполняется перед рендерингом страницы и может:

  • Проверять авторизацию пользователя.
  • Подготавливать данные, общие для всех маршрутов группы.
  • Перенаправлять на другие страницы при необходимости.

Пример middleware для группы маршрутов:

export function middleware(req, ctx) {
    if (!req.user) {
        return Response.redirect("/login");
    }
    return ctx.next();
}
  • ctx.next() — передача управления следующему обработчику или маршруту.

Layout и переиспользуемые компоненты

Для групп маршрутов часто используют общие layout-компоненты, которые оборачивают содержимое всех страниц группы. Это позволяет:

  • Единообразно отображать навигацию и футер.
  • Передавать общие данные (например, профиль пользователя) во все компоненты группы.
  • Сокращать дублирование кода.

Пример layout для группы dashboard:

export default function DashboardLayout({ children, user }) {
    return (
        <div>
            <Sidebar user={user} />
            <main>{children}</main>
        </div>
    );
}

Каждый маршрут внутри dashboard использует этот layout автоматически, что упрощает поддержку интерфейса.


Кэширование и оптимизация

Fresh интегрирует кэширование на уровне маршрутов и компонентов. Возможности включают:

  • Edge caching — кэширование готового HTML на CDN.
  • Incremental rendering — обновление только изменившихся компонентов.
  • Smart hydration — загрузка JavaScript только там, где это необходимо для интерактивности.

Благодаря этим механизмам страницы остаются быстрыми, даже если приложение содержит десятки или сотни маршрутов.


Итоговые особенности Fresh

  • Серверная генерация HTML и минимальная клиентская нагрузка.
  • Файловая маршрутизация с поддержкой динамических сегментов.
  • Лёгкая группировка маршрутов и общие layout-компоненты.
  • Middleware для управления доступом и подготовкой данных.
  • Оптимизация загрузки и кэширование на уровне маршрутов.

Fresh сочетает в себе удобство SPA и производительность традиционных SSR-приложений, обеспечивая современную архитектуру для масштабируемых веб-приложений.