Fresh — современный фреймворк для разработки веб-приложений на базе JavaScript и Deno, ориентированный на создание быстрых, лёгких и оптимизированных страниц. Одной из ключевых особенностей Fresh является концепция островов (islands), позволяющая сочетать статическую генерацию и интерактивные элементы без потери производительности.
Остров — это автономный интерактивный компонент, который может содержать JavaScript, управлять состоянием и взаимодействовать с пользователем. В отличие от традиционных SPA, где весь интерфейс рендерится на клиенте, Fresh использует гибридный подход:
Преимущества островов:
Для создания острова используется директива
export default в компоненте, а подключение происходит через
специальный хелпер Island.
Пример структуры острова:
// components/Counter.tsx
/** @jsx h */
import { h } from "preact";
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
/** @jsx h */
import { h } from "preact";
import Counter from "../components/Counter.tsx";
import { Island } from "$fresh/runtime.ts";
export default function Home() {
return (
<div>
<h1>Главная страница</h1>
<Island component={Counter} />
</div>
);
}
Ключевые моменты:
Counter полностью автономен и может содержать
любое состояние.<Island component={Counter} /> указывает Fresh,
что этот компонент нужно инициализировать на клиенте после загрузки
HTML.Острова в Fresh используют хуки Preact, такие как
useState и useEffect. Поскольку остров
изолирован, его состояние не влияет на другие части страницы, если не
передавать данные явно через пропсы или контекст.
Пример с эффектами:
import { h } from "preact";
import { useEffect, useState } from "preact/hooks";
export default function Clock() {
const [time, setTime] = useState(new Date().toLocaleTimeString());
useEffect(() => {
const interval = setInterval(() => {
setTime(new Date().toLocaleTimeString());
}, 1000);
return () => clearInterval(interval);
}, []);
return <p>Текущее время: {time}</p>;
}
Здесь компонент Clock обновляет своё состояние каждую
секунду, но остальная страница остаётся полностью статической.
Fresh позволяет загружать острова лениво, чтобы уменьшить нагрузку на клиент:
<Island component={Counter} defer />
defer — атрибут, который откладывает инициализацию до
полной загрузки HTML.Остров может принимать пропсы с сервера, что позволяет строить динамические интерфейсы без лишних запросов:
// routes/index.tsx
import Greeting from "../components/Greeting.tsx";
import { Island } from "$fresh/runtime.ts";
export default function Home() {
return (
<div>
<Island component={Greeting} name="Алексей" />
</div>
);
}
// components/Greeting.tsx
export default function Greeting({ name }: { name: string }) {
return <p>Привет, {name}!</p>;
}
Таким образом, данные передаются сразу при рендере страницы, без дополнительного API-запроса.
localStorage.Использование островов позволяет строить:
Комбинация статической генерации и динамических островов делает Fresh подходящим для сложных веб-приложений, где критична производительность и скорость загрузки.