Когда мы перезапускали x-developers.com, рассматривали три варианта: Next.js со статическим экспортом, чистый Vite + Vanilla, и Astro. Победил Astro — и вот почему.
Static-first как принцип
Маркетинговый сайт — это документ, не приложение. Он почти не меняется между визитами одного пользователя. Любой клиентский JS, который ты ему отдаёшь, должен быть оправдан конкретной интерактивностью.
Astro по умолчанию ship’ит ноль клиентского JS. Если компоненту нужна интерактивность — добавляешь её точечно через <script> или islands. Это идеальный default для лендинга.
Что мы получили
- LCP < 1с на mobile 3G
- 27 KB HTML с инлайн-CSS — один HTTP-запрос до first paint
- 5 KB client JS только на модалке интейка (Reveal-анимации — inline 600 байт)
- Lighthouse 98+ на всех категориях
Для сравнения: Next.js со статическим экспортом дал бы ~70 KB фреймворка в бандле даже без серверного рендера.
Где Astro ломается
Когда нужны интерактивные islands с серьёзным состоянием — компонентный язык .astro не помогает (он чисто шаблонный). Мы держим клиентскую логику на vanilla TS внутри <script> блоков. Работает, но если островов станет десяток — перейдём на Preact или Solid через @astrojs/preact.
Стек
Astro 5 + Tailwind v4 (CSS-first config через @theme) + TypeScript strict + Geist Sans/Mono. Без CMS — контент в TS-файлах и Content Collections. Деплой через rsync на nginx.