Astro 7: ewolucja czy rewolucja w szybkości buildów?
To rozróżnienie jest istotne, więc powiem od razu, zanim wciągnie nas marketing: benchmarki Astro 7 mierzą proces budowania, a nie wynik czy Core Web Vitals. Po aktualizacji wynik może pozostać podobny, ale trzeba go ponownie zmierzyć, ponieważ zmiany w generowanym HTML-u, integracjach i zależnościach nadal mogą wpłynąć na stronę. Jak uzyskać wysoką ocenę po stronie użytkownika, pokazuję w case study Lighthouse 100/100 w Astro. Tutaj interesuje nas koszt wyprodukowania i wdrożenia strony: czas maszyny CI, czas oczekiwania zespołu i szybkość dostarczenia 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 nowego w Astro 7: kluczowe zmiany dla buildów i CI/CD
Szybszy build w Astro 7: najważniejsza zmiana tej wersji
Zacznijmy od rzeczy najważniejszej, bo to ona uzasadnia całe wydanie. Astro przepisało na nowo trzy najwolniejsze fragmenty procesu budowania:
- Nowy kompilator
.astrow Rust — pełne przepisanie poprzedniego kompilatora w Go, zbudowane naoxc(parsing) i Lightning CSS (scoping CSS). Sam w sobie daje ok. 6% na dużym projekcie, bo kompilacja.astrorzadko 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 napisanym w Rust. Deklarowane 10–30× dotyczy benchmarków samego Rolldown względem Rollupa, a nie całego builda Astro. Vite zachowuje warstwę zgodności i automatycznie tłumaczy wiele ustawień esbuild oraz rollupOptions, jednak pluginy korzystające z wewnętrznych API nadal wymagają kontroli.
Suma tych zmian dała w oficjalnych testach 15–61% krótszy build, a część prób była ponad dwukrotnie szybsza. Poniższe liczby pochodzą z ogłoszenia Astro 7 i zostały zmierzone na MacBooku Pro z M4 Pro oraz 48 GB pamięci:
| Projekt | Astro 6 | Astro 7 | Zysk |
|---|---|---|---|
| docs.astro.build (~6 313 stron) | 114,54 s | 73,53 s | ~36% |
| astro.build (~308 stron) | 62,70 s | 24,24 s | ~61% |
| biomejs.dev (~6 488 stron) | 176,39 s | 149,90 s | ~15% |
| developers.cloudflare.com (8 431 stron) | 386,89 s | 261,94 s | ~32% |
| tauri.app (7 117 stron) | 86,12 s | 55,33 s | ~36% |
| aspire.dev (13 275 stron) | 385,84 s | 326,11 s | ~15% |
Przełóżmy to na biznes. Załóżmy build trwający 6 minut, który schodzi do 4. Przy 20 uruchomieniach dziennie daje to 40 minut mniej czasu maszyny, czyli około 13 godzin w miesiącu roboczym. Oszczędność na fakturze zależy jednak od sposobu naliczania czasu, klasy runnera, równoległości i tego, czy skrócenie mieści się w tym samym progu rozliczeniowym. Krótszy build może być cenniejszy jako krótsza pętla „commit → podgląd → decyzja” niż jako sama redukcja rachunku.
Nasza ocena: wydajność builda jest najmocniejszą częścią tego wydania, ale sama nie uzasadnia migracji w każdym projekcie. Im większy udział Markdown/MDX, kompilacji .astro i generowania stron, tym większa szansa na zauważalny zysk. Przy małym serwisie ograniczeniem mogą być instalacja zależności, testy, optymalizacja obrazów albo czas oczekiwania na runner.
Jak zmierzyć koszt builda przed migracją?
Nie porównuj pojedynczego lokalnego uruchomienia Astro 6 z jednym buildem Astro 7 w CI. Przygotuj powtarzalny pomiar:
- Uruchom obie wersje na tym samym commicie, runnerze, systemie, wersji Node.js i menedżerze pakietów.
- Oddziel czas kolejki, instalacji, lintowania, kontroli typów, testów,
astro build, optymalizacji obrazów, uploadu artefaktów i wdrożenia. - Wykonaj co najmniej pięć prób z pustym cache'em oraz pięć z cache'em rozgrzanym. Porównaj medianę i najwolniejszą typową próbę, nie rekord.
- Zapisz czas CPU, szczyt pamięci, rozmiar artefaktu i liczbę wygenerowanych stron. Szybszy proces, który przekracza pamięć runnera, nie jest tańszy.
- Sprawdź wynikowy HTML, zasoby i błędy, aby nie uznać przerwanego lub niepełnego builda za poprawę wydajności.
Najprostsza kalkulacja kosztu to liczba uruchomień × rozliczony czas × stawka runnera. Do decyzji biznesowej dodaj czas oczekiwania człowieka, odsetek anulowanych pipeline'ów i liczbę ponowień. Mierz koszt zaakceptowanego wdrożenia, a nie wyłącznie koszt jednego zielonego zadania.
Sätteri w Astro 7: szybszy kompilator i ryzyko migracji
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.
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:
Dodam jeszcze, że 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 w Astro 7: 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:
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:
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 i agentów AI
Astro 7 nie dodaje natywnego wsparcia dla llms.txt. Generowanie tego pliku, wersji .md stron dla crawlerów AI czy JSON-LD wymaga własnego endpointu albo integracji społeczności. Integrację traktuj jak każdą zależność: sprawdź zgodność z Astro 7, wygenerowany format, aktualizację po zmianie treści i wpływ na czas builda. Implementację opisuję w przewodniku o pliku llms.txt.
Astro rozwija obsługę agentów AI. Nie zmienia to sposobu renderowania strony, ale upraszcza automatyczne uruchamianie środowiska deweloperskiego i analizę logów przez narzędzia.
Przykładem jest serwer deweloperski działający w tle. Agenci AI mają problem z procesami, które nigdy się nie kończą: uruchamiają serwer, czekają na zakończenie i blokują dalszą pracę. Astro 7 dodaje astro dev --background oraz może wykryć środowisko agenta i automatycznie włączyć ten tryb. Bez wykrytego agenta astro dev zachowuje się jak wcześniej.
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 jest na chodzie.
JSON logging. Logger Astro jest teraz w pełni konfigurowalny i dla agentów JSON włącza się automatycznie, ale strukturalne logi są tym, czego potrzebujesz do integracji z Kibaną, CloudWatch czy Grafana/Loki:
Jako ciekawostkę dodam, że JSON logging był najczęściej głosowaną prośbą o funkcję na roadmapie Astro. Nie z powodu AI, tylko dlatego, że dotychczasowe logi (kolory, ramki ASCII) były nieparsowalne dla narzędzi do agregacji. To ciekawy przypadek, bo z jednej strony, wszyscy ją chcieli, a z drugiej jest to funkcja dla AI.
Czy warto migrować do Astro 7 teraz? Analiza ryzyka
Astro 7 może nie wymagać zmian w kodzie projektu, ale major obejmuje kilka niezależnych zmian. Nowy kompilator jest bardziej rygorystyczny i może zatrzymać build, który na Astro 6 przechodził bez problemu. Poprzedni kompilator w Go po cichu poprawiał część niepoprawnego HTML-u. Nowy tego nie robi:
- Niezamknięte tagi (
<div>Hellozamiast<div>Hello</div>) teraz rzucają błędem zamiast być cicho korygowane. - Brak automatycznej korekty HTML, przykładowo
<div>wewnątrz<p>nie będzie już przenoszony. Build może się udać, ale przeglądarka samodzielnie naprawi DOM, dlatego wynik trzeba porównać wizualnie i strukturalnie. - Białe znaki w stylu JSX. Odstępy między elementami są teraz zwijane jak w React.
<span>Hello</span>i<span>World</span>w osobnych liniach mogą wyrenderować się jako „HelloWorld”. Poprzednie zachowanie można tymczasowo zachować przezcompressHTML: true.
Do tego Vite 8 wymaga Node.js 20.19+ albo 22.12+ i może ujawnić problemy integracji zależnych od wewnętrznych API Vite. Astro 7 usuwa też @astrojs/db, usuwa część dawnych eksportów astro:transitions i zmienia zalecany import getContainerRenderer() na dedykowane ścieżki container-renderer. To są równie ważne punkty migracji jak kompilator.
| Kiedy migrować teraz | Kiedy świadomie poczekać |
|---|---|
| Masz dużą stronę treściową (tysiące podstron, dużo Markdown) — tu zysk z builda jest największy | Krytyczny projekt legacy bez budżetu na testy regresyjne |
| Płacisz za czas CI/CD i build to realna pozycja w budżecie | Mocno 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 7 | Jesteś w trakcie krytycznego release'u — nie mieszaj migracji majora z deadline'em |
Migracja do Astro 7: podejście Safe Upgrade
Zacznij od npx @astrojs/upgrade, które aktualizuje Astro i oficjalne integracje, ale nie traktuj pomyślnego zakończenia polecenia jak testu zgodności projektu. Zachowaj poprzedni lockfile oraz artefakt produkcyjny, aby plan wycofania nie wymagał odtwarzania wersji zależności z pamięci.
Tak migrujemy projekty klientów w Astro i Next.js bez przestojów:
Branch + zielony CI. Migracja na osobnej gałęzi, build i testy muszą przejść, zanim cokolwiek dotknie
main.Najpierw kompilator, a potem Markdown. Aktualizuj do Astro 7, zostań przy
unifieddla Markdown, napraw błędy nowego kompilatora (niezamknięte tagi, niepoprawne zagnieżdżenia). Sätteri to osobny, drugi krok.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.
Regresja wizualna i CSS. Nowy kompilator może inaczej zapisać kolory i wartości
url(). Nie każda różnica tekstowa jest błędem, dlatego połącz snapshoty kodu z porównaniem obrazu strony.Pluginy i integracje. Sprawdź zgodność z Vite 8 zanim, a nie po tym jak, odpalisz build na produkcji.
Runtime i usunięte API. Sprawdź wersję Node.js w CI i hostingu,
@astrojs/db, importy Container API oraz usunięte elementyastro:transitions.Deploy preview. Wdrożenie na środowisko preview z realnym ruchem testowym, dopiero potem produkcja.
Co naprawdę obniża koszt CI/CD poza Astro 7?
Szybszy framework pomaga tylko w części pipeline'u. W wielu repozytoriach większy efekt dają zmiany organizacyjne i konfiguracyjne:
- Anuluj pipeline'y zastąpione nowszym commitem. W sytuacji kiedy po minucie pojawia się kolejny push do tej samej gałęzi, starszy build podglądu zwykle nie ma już wartości.
- Uruchamiaj zadania tylko dla właściwych ścieżek. W monorepo zmiana backendu lub dokumentacji wewnętrznej nie zawsze musi budować publiczny serwis Astro. Filtry muszą jednak uwzględniać współdzielone pakiety i konfigurację.
- Buforuj właściwą warstwę. Cache menedżera pakietów kluczuj lockfile'em, wersją Node.js i platformą. Nie buforuj bezwarunkowo całego
node_modules, bo łatwo ukryć różnice binariów natywnych. - Buduj artefakt jeden raz. Ten sam sprawdzony katalog wynikowy promuj między etapami, zamiast ponownie instalować zależności i budować osobno dla każdego środowiska. Konfiguracja zależna od środowiska musi być wtedy wstrzykiwana świadomie.
- Rozdziel testy od krytycznej ścieżki. Szybkie kontrole blokują preview, a cięższe testy mogą działać równolegle. Nie oznacza to pomijania kontroli przed produkcją, tylko lepszy graf zależności.
- Dobierz runner na podstawie pomiaru. Mocniejsza maszyna może skończyć szybciej, ale kosztować więcej; tańsza może być opłacalna, dopóki nie zaczyna korzystać ze swapu lub tworzyć kolejki.
Najpierw zoptymalizuj najdłuższy etap. Jeżeli astro build stanowi 25% czasu pipeline'u, nawet skrócenie go o 60% zmniejszy cały proces tylko o około 15%. To prosty odpowiednik prawa Amdahla i dobry filtr na marketingowe benchmarki.
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, a nie od wersji frameworka. Pokażę, co realnie warto włączyć w astro.config.mjs, żeby wykorzystać potencjał siódemki:
Ten cache ma znaczenie wyłącznie dla odpowiedzi renderowanych na żądanie. Nie przyspieszy dostarczenia trasy, która już podczas builda została wygenerowana jako statyczny plik i jest serwowana przez CDN. memoryCache() nie jest też współdzielony między wieloma instancjami procesu, dlatego po restarcie lub skalowaniu może mieć niski współczynnik trafień. Cache jest wyłączony w trybie deweloperskim, więc hit ratio i TTFB mierz na produkcyjnym buildzie lub środowisku preview, nie przez samo astro dev.
Czego nie musisz już robić? Kompilator w Rust i queued rendering są nowym zachowaniem domyślnym. Advanced Routing oraz konfigurowalny logger są stabilne, ale korzystasz z nich dopiero przez src/fetch.ts albo konfigurację logger. Route caching również jest stabilne, lecz wymaga dostawcy cache i reguł. Usuń dawne flagi experimental.queuedRendering, experimental.rustCompiler, experimental.advancedRouting, experimental.logger oraz experimental.cache; konfigurację cache przenieś na najwyższy poziom.
Gdzie realnie biorą się zyski ? Oficjalne benchmarki Astro 7 dotyczą czasu builda, a nie TTFB i dla stron prerenderowanych (SSG) TTFB zależy od CDN. Realna poprawa TTFB w Astro 7 pochodzi z route caching dla stron renderowanych na żądanie — szczególnie z nowych dostawców cache CDN:
Tu ważne jest rozróżnienie statusów: samo route caching jest już stabilne, ale wszyscy trzej dostawcy CDN (cacheNetlify(), cacheVercel(), cacheCloudflare()) są nadal eksperymentalni. Aktualna dokumentacja adaptera Cloudflare wskazuje, że potrzebna obsługa Workers Cache jest włączana z ustawieniami domyślnymi, gdy skonfigurujesz cacheCloudflare(); informacja o wymaganej prywatnej becie jest już nieaktualna. Dostawców CDN nadal testuj na podglądzie, sprawdzając nagłówki, trafienia, inwalidację i zachowanie po wdrożeniu nowej wersji.
Trafienie w cache CDN może zostać obsłużone bez uruchamiania funkcji serwerowej, co zmniejsza TTFB i liczbę wywołań. Nie cache'uj jednak odpowiedzi zależnych od sesji, cookies, uprawnień lub koszyka wspólnym kluczem. Błąd cache może ujawnić dane, dlatego testuj warianty zalogowany/niezalogowany, różne języki, parametry oraz awarię webhooka inwalidującego.
Endpoint inwalidacji zabezpiecz podpisem lub sekretem, ogranicz do metody POST i loguj odrzucone wywołania. cache.invalidate() zgłasza błąd, gdy dostawca nie jest skonfigurowany, dlatego kod używany w kilku środowiskach powinien wcześniej sprawdzić cache.enabled.
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:
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 w Astro 7: jak nowości pomagają w utrzymaniu projektu
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.
