Astro 7: Buildy szybsze o 61%. Przegląd nowości, które realnie tną koszty CI/CD

Opublikowano
24 czerwca 2026
Aktualizacja
24 czerwca 2026
Czas czytania
12 min czytania

Astro 7 – ewolucja czy rewolucja?

To rozróżnienie jest istotne, więc powiem od razu, zanim wciągnie nas marketing: Astro 7 nie przyspieszy Twojej strony dla użytkownika w sposób, który zobaczysz w . Jeśli na Astro 6 miałeś 100/100, na Astro 7 dalej będziesz mieć 100/100 — jak w naszym case study Lighthouse 100/100 w Astro. To, co realnie się zmienia, to ile kosztuje Cię wyprodukowanie i wdrożenie tej strony — a to akurat liczba, którą widać na fakturze za CI/CD i w czasie do wdrożenia kolejnej zmiany.

Większość blogów skupi się teraz na składni src/fetch.ts i na tym, że „kompilator jest w Rust". Ja skupię się na czymś innym: które z tych zmian realnie obniżają koszt utrzymania projektu, a które są ładnym nagłówkiem, który w Twoim konkretnym przypadku nic nie zmieni. I gdzie jest haczyk, o którym Astro w komunikacie prasowym pisze drobnym drukiem.

Co faktycznie się zmieniło? Kluczowe nowości

Szybszy build to jest cała ta wersja — i to działa

Zacznijmy od rzeczy najważniejszej, bo to ona uzasadnia całe wydanie. Astro przepisało na nowo trzy najwolniejsze fragmenty procesu budowania:

  • Nowy kompilator .astro w Rust — pełne przepisanie poprzedniego kompilatora w Go, zbudowane na oxc (parsing) i Lightning CSS (scoping CSS). Sam w sobie daje ok. 6% na dużym projekcie, bo kompilacja .astro rzadko jest wąskim gardłem.
  • Sätteri — nowy pipeline Markdown/MDX w Rust — zastępuje domyślnie dotychczasowy unified (remark/rehype). To tutaj na stronach z dużą ilością Markdown dzieją się największe oszczędności.
  • Kolejkowane renderowanie (queued rendering) — silnik renderowania znany z Astro 6 jako eksperyment, teraz stabilny i domyślny. Według Astro ok. 2,4× szybszy od poprzedniego, rekurencyjnego podejścia i do tego mniej pamięciożerny.

Do tego dochodzi Vite 8 z bundlerem Rolldown (też Rust), który wg benchmarków jest 10–30× szybszy od Rollupa, przy zachowaniu zgodności API pluginów.

Suma tych zmian to oficjalnie 15–61% krótszy build, a w skrajnych przypadkach ponad dwukrotnie szybszy. Oto prawdziwa tabela benchmarków Astro (MacBook Pro M4 Pro, 48 GB RAM) — nie nasze szacunki, tylko dane z oficjalnego wydania:

ProjektAstro 6Astro 7Zysk
docs.astro.build (~6 313 stron)114,54 s73,53 s~36%
astro.build (~308 stron)62,70 s24,24 s~61%
biomejs.dev (~6 488 stron)176,39 s149,90 s~15%
developers.cloudflare.com (8 431 stron)386,89 s261,94 s~32%
tauri.app (7 117 stron)86,12 s55,33 s~36%
aspire.dev (13 275 stron)385,84 s326,11 s~15%

Przełóżmy to na biznes. Załóżmy build trwający 6 minut, który schodzi do 4. Jeśli zespół wdraża 20 razy dziennie, to 40 minut dziennie odzyskanego czasu maszyny CI — w skali miesiąca 14+ godzin. Przy płatnym runnerze to realna pozycja w budżecie. Ale ważniejszy jest efekt miękki: krótszy build to krótsza pętla „commit → podgląd → decyzja", a to bezpośrednio przekłada się na czas wprowadzenia zmiany na rynek. Dla projektu treściowego (dokumentacja, duży blog, e-commerce z tysiącami stron produktowych) różnica między 3 a 6 minutami builda jest różnicą między „wrzucam poprawkę przed kawą" a „odpalam i robię sobie przerwę".

Nasza szczera ocena: to najmocniejsza część tego wydania i jedyny argument, który dla większości firm sam w sobie uzasadnia aktualizację. Im więcej masz Markdown/MDX i im więcej stron, tym bardziej Cię to dotyczy — i odwrotnie: przy małej wizytówce na kilkanaście podstron różnica jest do pominięcia.

Sätteri: szybciej, ale tu jest haczyk migracyjny

Sätteri zasługuje na osobny akapit, bo to zmiana, która może Cię zaskoczyć przy migracji. Dotychczas Astro przetwarzało Markdown przez unified — każdy plik parsowany w JS, przepuszczany plugin po pluginie przez całe drzewo AST, potem serializowany z powrotem do HTML. Na dużych stronach to był najwolniejszy etap builda. Sätteri (pulldown-cmark + Oxc, natywny Rust) robi to dużo szybciej i przy okazji wbudowuje natywnie funkcje, które wcześniej wymagały osobnych pluginów: GFM, smart punctuation, heading IDs, container directives, math, frontmatter, sub/superscript, wikilinks.

Code
// astro.config.mjs — włączanie opcjonalnych funkcji Sätteri
import { defineConfig } from 'astro/config'
import { satteri } from '@astrojs/markdown-satteri'
 
export default defineConfig({
  markdown: {
    processor: satteri({
      features: {
        directive: true,
        math: true,
        headingAttributes: true,
      },
    }),
  },
})

Haczyk: jeśli Twój projekt opiera się na konkretnych pluginach remark/rehype (a w naszych projektach treściowych to norma — własne pluginy do osadzania komponentów, modyfikacji nagłówków, własne dyrektywy), to przeskok na Sätteri nie jest automatyczny. Ekosystem pluginów unified nie działa na Sätteri 1:1. Astro daje furtkę — stary pipeline jest dalej dostępny:

Code
// astro.config.mjs — pozostanie przy unified (remark/rehype)
import { defineConfig } from 'astro/config'
import { unified } from '@astrojs/markdown-remark'
import remarkToc from 'remark-toc'
 
export default defineConfig({
  markdown: {
    processor: unified({
      remarkPlugins: [remarkToc],
    }),
  },
})

I tu nasza rada: jeśli masz rozbudowany pipeline Markdown z własnymi pluginami, najpierw zostań przy unified i zaktualizuj resztę, a migrację na Sätteri potraktuj jako osobny, kontrolowany krok z testami regresyjnymi na renderowanym HTML. Inaczej zmieszasz dwie zmienne i nie będziesz wiedział, co Ci popsuło wynikowy HTML.

Advanced Routing: pełna kontrola nad pipeline'em żądania

To realnie nowa funkcja, która zastępuje w tym przeglądzie temat „izolacji ciężkich komponentów". Astro przez lata dokładało elementy serwerowe — middleware, redirects, rewrites, Actions, sessions, i18n — ale kolejność ich wykonania była sztywna i trudna do kontroli. Jeśli chciałeś, żeby autoryzacja działała przed Actions, albo żeby logowanie czasu odpowiedzi obejmowało tylko rendering stron, musiałeś to obchodzić.

Astro 7 wprowadza plik src/fetch.ts — standardowy handler fetch, ten sam wzorzec, który znasz z Cloudflare Workers, Deno i Bun:

Code
// src/fetch.ts
import { astro, FetchState } from 'astro/fetch'
 
export default {
  fetch(request: Request) {
    const state = new FetchState(request)
 
    // Przekieruj /api do zewnętrznego backendu (np. ciężki serwis AI)
    if (state.url.pathname.startsWith('/api')) {
      const url = new URL(
        state.url.pathname + state.url.search,
        'https://backend-api.example.com',
      )
      return fetch(new Request(url, request))
    }
 
    // Reszta leci normalnie przez strony/endpointy Astro
    return astro(state)
  },
}

Tu właśnie izolujesz ciężkie rzeczy — np. odpytywanie modelu AI czy wolny serwis zewnętrzny — zanim w ogóle dotkną pipeline'u renderującego strony. API jest kompatybilne z Hono, więc możesz wpiąć middleware Hono i ułożyć kolejność dokładnie tak, jak potrzebujesz:

Code
// src/fetch.ts — komponowanie pipeline'u z pełną kontrolą kolejności
import { Hono } from 'hono'
import { actions, middleware, pages, i18n } from 'astro/hono'
import { auth } from './middleware/auth'
import { timing } from './middleware/timing'
 
const app = new Hono()
 
app.use(i18n())
app.use(auth()) // Auth PRZED actions — żadnych nieautoryzowanych wywołań
app.use(actions())
app.use(middleware())
app.use(timing()) // Pomiar czasu obejmuje tylko rendering stron
app.use(pages())
 
export default app

Jeśli nie dodasz src/fetch.ts, Astro zachowuje się dokładnie jak wcześniej. Uwaga praktyczna: src/fetch.ts to teraz zarezerwowana nazwa pliku — jeśli masz w projekcie coś o tej nazwie, kolizja Cię zaskoczy.

Astro 7 a era LLM-ów: co tu jest prawdą, a co mitem

Astro 7 nie dodaje natywnego wsparcia dla llms.txt. Generowanie llms.txt, lustrzanych wersji .md stron dla crawlerów AI czy JSON-LD ogarniają integracje społeczności (jak astro-slop, @rafters/astro-meta, Agent Markup czy astro-mark-don), a nie sam rdzeń frameworka. Jeśli budujesz pod GEO/AEO, dalej sięgasz po integracje — jak opisałem w przewodniku o pliku llms.txt.

Prawdziwa „AI-First" historia tej wersji jest inna i — moim zdaniem — ciekawsza: Astro stawia na development sterowany agentami AI. To zakład o to, jak będzie wyglądać codzienna praca przy kodzie, a nie o to, jak strona ma wyglądać dla crawlera.

Background dev server. Agenty AI mają realny problem z procesami, które nigdy się nie kończą — odpalają dev server, czekają na zakończenie, i wiszą. Astro 7 dodaje astro dev --background, a co ważniejsze: wykrywa, że działa wewnątrz agenta AI i włącza tryb background automatycznie. Bez agenta astro dev zachowuje się jak zawsze.

Code
$ astro dev --background
Dev server running at http://localhost:4321 (pid 12345)
  Stop:   astro dev stop
  Status: astro dev status
  Logs:   astro dev logs

Lockfile zapobiega odpalaniu duplikatów, a każda komenda jest idempotentna (zatrzymanie nieuruchomionego serwera kończy się cicho sukcesem). Jest też endpoint /_astro/status do sprawdzenia, czy serwer żyje.

JSON logging. Logger Astro jest teraz w pełni konfigurowalny. Dla agentów JSON włącza się automatycznie, ale — i to jest argument dla zespołów produkcyjnych, nie tylko dla AI — strukturalne logi są tym, czego potrzebujesz do integracji z Kibaną, CloudWatch czy Grafana/Loki:

Code
// astro.config.mjs — logi czytelne dla człowieka I dla maszyny jednocześnie
import { defineConfig, logHandlers } from 'astro/config'
 
export default defineConfig({
  logger: logHandlers.compose(logHandlers.console(), logHandlers.json()),
})

Ciekawostka: JSON logging był najczęściej głosowaną prośbą o funkcję na roadmapie Astro — i wcale nie z powodu AI, tylko dlatego, że dotychczasowe logi (kolory, ramki ASCII) były nieparsowalne dla narzędzi do agregacji. To rzadki przypadek, gdy „funkcja dla AI" okazuje się po prostu dobrą funkcją produkcyjną, którą wszyscy chcieli od dawna.

Czy warto migrować teraz? Analiza ryzyka

Astro 7 jest bezpieczniejsze w migracji niż brzmi jest tylko małe ALE. Nowy kompilator jest dużo bardziej rygorystyczny i może wywalić build, który na Astro 6 przechodził bez problemu. Poprzedni kompilator w Go po cichu „naprawiał" niepoprawny HTML. Ten nowy tego nie robi:

  • Niezamknięte tagi (<div>Hello zamiast <div>Hello</div>) teraz rzucają błędem zamiast być cicho korygowane.
  • Brak auto-korekty HTML — np. <div> wewnątrz <p> nie będzie już przenoszony; wynik zostawiony jest przeglądarce. To może zmienić wyrenderowany HTML w miejscach, gdzie wcześniej kompilator „sprzątał" po Tobie.
  • Whitespace w stylu JSX — odstępy między elementami są teraz zwijane jak w React. <span>Hello</span> i <span>World</span> w osobnych liniach wyrenderują się jako „HelloWorld" bez spacji.

Do tego Vite 8 łamie zgodność dla integracji i pluginów zależnych od wewnętrznych API Vite (sam kod projektu zwykle przechodzi bez zmian dzięki warstwie kompatybilności).

Kiedy migrować terazKiedy świadomie poczekać
Masz dużą stronę treściową (tysiące podstron, dużo Markdown) — tu zysk z builda jest największyKrytyczny projekt legacy bez budżetu na testy regresyjne
Płacisz za czas CI/CD i build to realna pozycja w budżecieMocno zależysz od pluginów remark/rehype i nie masz czasu na walidację wyniku Sätteri
Chcesz route caching + integrację z edge (Netlify/Vercel/Cloudflare)Twoje integracje/pluginy nie ogłosiły jeszcze zgodności z Vite 8
Twój workflow korzysta z agentów AI (Cursor, Claude Code itp.)Masz w szablonach „tolerowany" niepoprawny HTML i nie wiesz, ile go jest
Zaczynasz nowy projekt — wchodź od razu na 7Jesteś w trakcie krytycznego release'u — nie mieszaj migracji majora z deadline'em

Rada StriveLab: podejście „Safe Upgrade"

Tak migrujemy projekty klientów w Astro i Next.js bez przestojów:

  1. Branch + zielony CI. Migracja na osobnej gałęzi, build i testy muszą przejść, zanim cokolwiek dotknie main.
  2. Najpierw kompilator, a potem Markdown. Aktualizuj do Astro 7, zostań przy unified dla Markdown, napraw błędy nowego kompilatora (niezamknięte tagi, niepoprawne zagnieżdżenia). Sätteri to osobny, drugi krok.
  3. Diff renderowanego HTML. Zbierz wyrenderowany HTML przed i po, porównaj. Tu wychodzą ciche zmiany whitespace'u i korekty HTML, których nie widać w kodzie źródłowym.
  4. Pluginy i integracje. Sprawdź zgodność z Vite 8 zanim, a nie po tym jak, odpalisz build na produkcji.
  5. Deploy preview. Wdrożenie na środowisko preview z realnym ruchem testowym, dopiero potem produkcja.

„Performance by default" – jak wycisnąć maksimum z Astro 7

Wynik strony dla użytkownika zależy od Twoich obrazków, fontów, skryptów firm trzecich i hostingu — nie od wersji frameworka. Dlatego zamiast obiecywać magiczne 100/100, pokażę, co realnie warto włączyć w astro.config.mjs, żeby wykorzystać potencjał siódemki:

Code
// astro.config.mjs — sensowny punkt startowy dla Astro 7
import { defineConfig, memoryCache } from 'astro/config'
import { satteri } from '@astrojs/markdown-satteri'
 
export default defineConfig({
  // 1. Route caching — teraz stabilny, nie trzeba flagi experimental
  cache: {
    provider: memoryCache(), // stabilny; provider CDN to wciąż funkcja eksperymentalna
  },
  routeRules: {
    '/blog/[...path]': { maxAge: 300, swr: 60 },
  },
 
  // 2. Sätteri — domyślny, ale tu jawnie włączasz dodatkowe funkcje
  markdown: {
    processor: satteri({
      features: { directive: true, math: true, headingAttributes: true },
    }),
  },
})

Czego nie musisz już robić: queued rendering, Rust compiler, advanced routing, logger i route caching są domyślne. Z configu znikają flagi experimental.queuedRendering, experimental.rustCompiler, experimental.advancedRouting, experimental.logger oraz experimental.cache (to ostatnie przenosisz do pola cache na najwyższym poziomie). Jeśli masz je z czasów Astro 6, po prostu posprzątaj.

Gdzie realnie biorą się zyski . To kluczowe, bo szkielet tego artykułu zakładał porównanie TTFB v6 vs v7 — a tu trzeba być uczciwym: oficjalne benchmarki Astro 7 dotyczą czasu builda, nie TTFB. Dla stron prerenderowanych (SSG) TTFB zależy od CDN, nie od wersji Astro. Realna poprawa TTFB w Astro 7 pochodzi z route caching dla stron renderowanych na żądanie — szczególnie z nowych dostawców cache CDN:

Code
// astro.config.mjs — cache na edge zamiast w pamięci serwera
import { defineConfig } from 'astro/config'
import netlify from '@astrojs/netlify'
import { cacheNetlify } from '@astrojs/netlify/cache'
 
export default defineConfig({
  adapter: netlify(),
  cache: {
    provider: cacheNetlify(), // trafienia serwowane prosto z CDN, bez wywołania funkcji serwerowej
  },
})

Tu ważne rozróżnienie statusów, bo łatwo się pomylić: samo route caching jest już stabilne, ale wszyscy trzej dostawcy CDN (cacheNetlify(), cacheVercel(), cacheCloudflare()) są jeszcze eksperymentalni — nie tylko Cloudflare. Cloudflare ma dodatkowy haczyk: wymaga dostępu do Cloudflare Workers Cache, który jest w prywatnej becie, więc bez niego po prostu nie zadziała. Praktycznie znaczy to tyle: cache w pamięci (memoryCache()) wdrażaj spokojnie, a dostawców CDN traktuj jako funkcję wczesną — przetestuj na podglądzie, zanim oprzesz na nich produkcję. Mechanizm jest prosty: trafienie w cache jest serwowane prosto z edge, bez uruchamiania Twojej funkcji serwerowej — i właśnie stąd bierze się obniżka TTFB. Jeśli chcesz zmierzyć różnicę na konkretnym projekcie, to jest dokładnie ten scenariusz, który warto zbenchmarkować (np. strona produktowa z danymi z CMS, przed i po włączeniu CDN cache).

Cache integruje się też z live content collections, a loader może dołączyć podpowiedź o cache (tagi do inwalidacji, czas modyfikacji). Astro czyta ją automatycznie:

Code
---
// src/pages/products/[id].astro
import { getLiveEntry } from 'astro:content';
const { entry } = await getLiveEntry('products', Astro.params.id);
 
// Astro czyta cache hint loadera z entry — bez ręcznych nagłówków
Astro.cache.set(entry);
---

A inwalidację po tagu spinasz z webhookiem CMS-a, żeby czyścić tylko to, co się zmieniło — bez przebudowy całej strony.

Bug debt: jak nowości pomagają w utrzymaniu

Wracając do wątku, który poruszałem wcześniej na blogu — typowych, cichych błędów w projektach Astro. Najciekawsze jest to, że najbardziej kontrowersyjna zmiana Astro 7 jest jednocześnie najlepszym narzędziem do redukcji długu technicznego.

Rygor nowego kompilatora boli przy migracji, ale działa jak darmowy linter szablonów. Niezamknięty tag, który poprzednio kompilator po cichu „naprawiał", był prawdziwym błędem — tylko nikt go nie widział, bo build przechodził. Teraz wychodzi na etapie builda, czyli w najtańszym możliwym momencie: zanim trafi na produkcję, zanim zobaczy go użytkownik, zanim ktoś otworzy ticket. To przesunięcie wykrywania błędów „w lewo" (shift-left) to dokładnie to, czego chcemy w zdrowym projekcie.

Podobnie strukturalne logi JSON: w utrzymaniu produkcyjnego SSR możliwość wpięcia logów w Grafana/Loki czy CloudWatch to różnica między „debugujemy po opisie użytkownika" a „mamy alert z tracem". To nie jest spektakularne, ale to jest właśnie to, co obniża koszt utrzymania w skali miesięcy.

Ultraszybkie projekty, łączące lekkość ze skalowalnością.
Astro

Często zadawane pytania

O ile naprawdę przyspiesza build w Astro 7?

Oficjalnie 15–61% krótszy build, w skrajnych przypadkach ponad dwukrotnie. Zysk rośnie z liczbą stron i ilością Markdown/MDX: astro.build (~308 stron) skrócił się o ~61%, docs.astro.build (~6 313 stron) o ~36%. Dla małej strony wizytówkowej różnica jest minimalna — nagłówek „60% szybciej" dotyczy projektów liczonych w tysiącach podstron.

Nie w sposób widoczny w Lighthouse. Astro już wcześniej serwowało statyczny HTML z minimalnym JS, więc jeśli na Astro 6 miałeś 100/100, na 7 dalej będziesz mieć 100/100. Astro 7 przyspiesza pracę zespołu (czas builda, pętlę zwrotną), nie rendering u użytkownika. Realna poprawa TTFB pochodzi z route cachingu dla tras renderowanych na żądanie, nie z samej wersji frameworka.

Nie. To popularny mit. Astro 7 nie dodaje natywnego wsparcia dla llms.txt — generowanie llms.txt, lustrzanych wersji .md stron czy JSON-LD ogarniają integracje społeczności (astro-slop, Agent Markup i inne), a nie rdzeń frameworka. Pod GEO/AEO dalej sięgasz po integracje.

Nowy kompilator w Rust jest dużo bardziej rygorystyczny niż poprzedni w Go. Niezamknięte tagi rzucają błędem zamiast być cicho korygowane, znika auto-korekta niepoprawnego zagnieżdżenia HTML, a whitespace zwijany jest jak w JSX (elementy w osobnych liniach mogą wyrenderować się bez spacji). Do tego Vite 8 łamie zgodność dla integracji zależnych od wewnętrznych API Vite.

Nie. Sätteri (nowy pipeline Markdown/MDX w Rust) jest domyślny, ale stary pipeline unified (remark/rehype) pozostaje dostępny. Jeśli opierasz się na własnych pluginach remark/rehype, najpierw zostań przy unified i zaktualizuj resztę, a migrację na Sätteri potraktuj jako osobny, kontrolowany krok z testami regresyjnymi na renderowanym HTML.

O autorze

Maciej Sala

Maciej Sala — Product Manager i Frontend Developer z bogatym doświadczeniem w marketingu internetowym oraz SEO. Na co dzień pracuje z Reactem, Next.js i TypeScriptem, a ostatnio także z Astro i narzędziami do automatyzacji procesów AI. Sprawnie łączy perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat był związany z branżą gier wideo jako project manager i game designer. Absolwent historii na Uniwersytecie Jagiellońskim oraz studiów podyplomowych z marketingu internetowego na AGH w Krakowie. Po godzinach trenuje na siłowni, maluje figurki i rozwija własne projekty side-projecty.

Pomagam przekładać takie tematy na konkretne wdrożenia w frontendzie, SEO, analityce i procesie produktowym.

Skontaktuj się ze mną

Biblioteka wiedzy

Czytaj dalej

Zobacz więcej wpisów