Fresh — это современный подход к построению реактивных веб-приложений на JavaScript, ориентированный на минимизацию избыточной загрузки данных и оптимизацию взаимодействия клиента с сервером. Основная цель Fresh — обеспечить свежесть данных без излишней сложности архитектуры и сложного состояния.
В ядре Fresh лежит концепция “request-context-driven rendering”. Каждое обращение к серверу рассматривается как отдельный контекст, в котором формируется полный набор данных, необходимых для рендеринга. Это позволяет:
Важное отличие Fresh от классических SPA-фреймворков состоит в том, что сервер формирует почти всю страницу, а клиент отвечает только за минимальную интерактивность.
Контекст запроса (request context) — это объект,
содержащий всю информацию, доступную во время обработки
HTTP-запроса:
const context = {
request: req, // объект запроса
params: req.params, // параметры URL
state: {}, // временное состояние для этого запроса
session: {}, // пользовательская сессия
};
Ключевые свойства контекста:
Контекст создаётся автоматически при каждом HTTP-запросе, что обеспечивает изоляцию данных между пользователями и запросами.
Обновление данных в Fresh строится вокруг принципа freshness — каждый запрос получает актуальные данные. Основные подходы:
Серверное обновление Сервер формирует страницу с актуальными данными при каждом запросе:
export async function handler(context) {
const data = await fetchDataFromDB();
return new Response(renderPage({ data }));
}
Данные не кэшируются на клиенте, что предотвращает устаревшую информацию.
Стратегия инкрементальной актуализации Используется для больших страниц или сложных данных:
Компоненты Fresh работают по принципу server-first rendering:
Пример реактивного компонента:
export default function Counter({ initial }) {
let count = initial;
function increment() {
count += 1;
updateDOM(); // минимальное вмешательство клиента
}
return html`
<div>
<span>${count}</span>
<button oncl ick=${increment}>+1</button>
</div>
`;
}
Ключевой момент — клиентская логика минимальна, а сервер формирует основное содержание страницы.
Fresh позволяет гибко управлять кэшированием:
Cache-Control, ETag) для статических
ресурсов;Пример установки кэш-заголовков:
export async function handler(context) {
const data = await fetchDataFromDB();
return new Response(renderPage({ data }), {
headers: { "Cache-Control": "max-age=0, must-revalidate" }
});
}
Такой подход гарантирует, что каждый новый запрос получает свежие данные, а кэш не блокирует обновление.
Fresh особенно эффективен при работе с внешними API:
Пример:
export async function handler(context) {
const userId = context.params.id;
const profile = await fetch(`https://api.example.com/users/${userId}`).then(r => r.json());
return new Response(renderPage({ profile }));
}
Актуальные данные при каждом запросе Исключается вероятность отображения устаревшей информации.
Изоляция состояния между запросами Ошибки одного пользователя не влияют на другого.
Минимальная клиентская нагрузка JavaScript на клиенте используется только для интерактивных элементов.
Простота интеграции с серверными ресурсами Все данные берутся из контекста запроса или внешних API.
Удобство масштабирования Серверные рендеры и реактивные компоненты позволяют легко добавлять новые страницы и функциональность без глобальных изменений состояния.
Fresh в JavaScript представляет собой мощный инструмент для построения быстрых, реактивных и всегда актуальных веб-приложений. Использование контекста запроса, server-first компонентов и продуманного кэширования позволяет достигать высокой производительности и надежности, при этом значительно снижая сложность клиентской логики.