15. SSR и SSG
Qwik City поддерживает несколько режимов рендеринга: Server-Side Rendering (SSR), Static Site Generation (SSG) и их комбинации. Выбор режима влияет на производительность, SEO и масштабируемость.
Режимы рендеринга
Заголовок раздела «Режимы рендеринга»SSR (Server-Side Rendering) ↳ HTML генерируется на сервере при каждом запросе ↳ Данные всегда актуальны ↳ Подходит: новостные сайты, личные кабинеты
SSG (Static Site Generation) ↳ HTML генерируется при сборке ↳ Максимальная скорость (отдаётся как файл) ↳ Подходит: блоги, документация, лендинги
ISR (Incremental Static Regeneration) ↳ Статика с периодическим обновлением ↳ Баланс между скоростью и актуальностью
Hybrid ↳ Разные маршруты — разные режимы ↳ / → SSG, /blog → SSR, /dashboard → SSRSSR по умолчанию
Заголовок раздела «SSR по умолчанию»В Qwik City все страницы рендерятся на сервере по умолчанию:
import { component$ } from '@builder.io/qwik';import { routeLoader$ } from '@builder.io/qwik-city';
// Этот загрузчик выполняется на сервере при каждом запросеexport const useNews = routeLoader$(async () => { const articles = await fetchLatestNews(); return articles;});
export default component$(() => { const news = useNews(); return ( <ul> {news.value.map(article => ( <li key={article.id}>{article.title}</li> ))} </ul> );});SSG — статическая генерация
Заголовок раздела «SSG — статическая генерация»Для статической генерации используется onStaticGenerate:
import type { StaticGenerateHandler } from '@builder.io/qwik-city';
// Указываем какие slug'и нужно сгенерироватьexport const onStaticGenerate: StaticGenerateHandler = async () => { const posts = await getAllPosts();
return { params: posts.map(post => ({ slug: post.slug })), };};
// Загрузчик данных работает и при SSGexport const usePost = routeLoader$(async ({ params }) => { return await getPost(params.slug);});Adapter для деплоя
Заголовок раздела «Adapter для деплоя»Режим рендеринга зависит от адаптера:
# Статический хостинг (SSG)npm run qwik add static
# Vercel Edge (SSR)npm run qwik add vercel-edge
# Cloudflare Workers (SSR)npm run qwik add cloudflare-pages
# Node.js (SSR)npm run qwik add expressCache Control заголовки
Заголовок раздела «Cache Control заголовки»// SSR с кешированиемexport const onGet: RequestHandler = ({ cacheControl }) => { // Кешируем на 1 час, stale 24 часа cacheControl({ maxAge: 3600, staleWhileRevalidate: 86400, public: true, });};useLocation и серверное состояние
Заголовок раздела «useLocation и серверное состояние»export const usePageData = routeLoader$(async ({ url, headers, cookie, env }) => { // url — текущий URL const page = Number(url.searchParams.get('page') ?? '1');
// headers — заголовки запроса const userAgent = headers.get('user-agent');
// cookie — куки const userId = cookie.get('userId')?.value;
// env — переменные окружения const apiKey = env.get('API_KEY');
return { page, userId };});Streaming SSR
Заголовок раздела «Streaming SSR»Qwik поддерживает потоковую передачу HTML:
// Qwik автоматически стримит HTML// Браузер начинает отображать контент до полной загрузки
// Компоненты с отложенными данными рендерятся asyncexport default component$(() => { const data = useLazyData(); // Отложенный загрузчик
return ( <div> <div>Это отображается сразу</div> <Suspense fallback={<div>Загрузка...</div>}> {/* Это появится когда data загрузится */} <DataComponent data={data} /> </Suspense> </div> );});