lenec ru

← все посты

Linux perf: профилирование CPU и поиск bottleneck в продакшене

15K

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 побеждает там, где контент важнее интерактивности. А это большинство сайтов в интернете.

Комментарии 0

  • Будьте первым, кто оставит комментарий.

Войдите, чтобы оставить комментарий.