Linux perf: профилирование CPU и поиск bottleneck в продакшене
Astro — фреймворк, который отправляет браузеру чистый HTML и ноль JavaScript по умолчанию. Интерактивные компоненты подключаются точечно — как «острова» в море статики. Это делает Astro идеальным для контентных сайтов, где скорость загрузки важнее сложной клиентской логики. Разберём архитектуру, возможности и сценарии использования.
Философия: zero JS by default, islands architecture
Большинство фреймворков (Next.js, Nuxt, SvelteKit) отправляют JavaScript для всей страницы — даже если 90% контента статично. Astro переворачивает подход: по умолчанию страница — чистый HTML. JavaScript подключается только к тем компонентам, которые действительно интерактивны.
---
// src/pages/index.astro — серверный код (frontmatter)
import Header from '../components/Header.astro';
import Newsletter from '../components/Newsletter.tsx';
const posts = await fetch('https://api.blog.com/posts').then(r => r.json());
---
<html>
<body>
<Header /> <!-- Статика: 0 KB JS -->
{posts.map(post => (
<article>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
<!-- Остров: React-компонент с интерактивностью -->
<Newsletter client:visible />
</body>
</html>
Директива client:visible означает: загрузить JS для этого компонента только когда он появится в viewport. Другие варианты: client:load (сразу), client:idle (когда браузер свободен), client:media (по media query).
Интеграции: React, Vue, Svelte в одном проекте
Уникальная фича Astro — поддержка нескольких UI-фреймворков одновременно:
---
// Можно использовать компоненты из разных фреймворков
import ReactCounter from '../components/Counter.tsx';
import VueModal from '../components/Modal.vue';
import SvelteForm from '../components/Form.svelte';
---
<ReactCounter client:load />
<VueModal client:idle />
<SvelteForm client:visible />
Это полезно при миграции: переносите проект постепенно, не переписывая всё сразу. Или используйте лучшие компоненты из разных экосистем. Каждый остров загружает только свой фреймворк — React-компонент не тянет Vue runtime.
Content Collections: типизированный контент
Astro предлагает встроенную систему для работы с Markdown/MDX контентом с полной типизацией:
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
date: z.date(),
tags: z.array(z.string()),
draft: z.boolean().default(false),
}),
});
export const collections = { blog };
---
// src/pages/blog/[slug].astro
import { getCollection } from 'astro:content';
export async function getStaticPaths() {
const posts = await getCollection('blog', ({ data }) => !data.draft);
return posts.map(post => ({
params: { slug: post.slug },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await post.render();
---
<article>
<h1>{post.data.title}</h1>
<time>{post.data.date.toLocaleDateString()}</time>
<Content />
</article>
Схема валидируется при сборке — опечатка в frontmatter ловится до деплоя, а не в продакшене.
View Transitions: SPA-навигация без JS-фреймворка
Astro поддерживает View Transitions API — плавные переходы между страницами без клиентского роутера:
---
// src/layouts/Base.astro
import { ViewTransitions } from 'astro:transitions';
---
<html>
<head>
<ViewTransitions />
</head>
<body>
<slot />
</body>
</html>
Одна строка — и навигация становится SPA-like: fade, slide, morph-анимации между страницами. При этом каждая страница остаётся полноценным HTML-документом. Работает в Chrome, Edge, Safari; в Firefox — graceful degradation до обычной навигации.
SSR vs SSG vs Hybrid: режимы рендеринга
SSG (по умолчанию) — все страницы генерируются при сборке. Идеально для блогов, документации, лендингов.
SSR — страницы рендерятся на сервере при каждом запросе. Для динамического контента, персонализации.
Hybrid — комбинация: большинство страниц статические, отдельные — серверные:
---
// src/pages/dashboard.astro
export const prerender = false; // эта страница — SSR
// Остальные страницы остаются статическими
const user = await getUser(Astro.cookies.get('session'));
---
<h1>Привет, {user.name}</h1>
Деплой SSR — на Node.js, Deno, Cloudflare Workers, Vercel, Netlify. Адаптеры подключаются одной строкой в конфиге.
Когда Astro лучше Next.js/Nuxt
Выбирай Astro, если:
- Контентный сайт: блог, документация, маркетинговые страницы, портфолио
- Критична скорость загрузки — 0 KB JS по умолчанию даёт 100/100 в Lighthouse
- Интерактивность точечная: форма подписки, поиск, карусель — но не весь UI
- Хотите использовать Markdown/MDX с типизацией
- Команда работает с разными фреймворками — Astro объединяет
Оставайся на Next.js/Nuxt, если:
- Приложение высокоинтерактивное: дашборды, редакторы, real-time
- Нужна сложная клиентская маршрутизация с состоянием
- Тяжёлый data fetching с кешированием (RTK Query, TanStack Query)
- Команда уже на Next.js/Nuxt и проект не контентный
Astro не конкурирует с Next.js напрямую — они для разных задач. Astro побеждает там, где контент важнее интерактивности. А это большинство сайтов в интернете.