OMASDEV Wiki← Wróć na stronę główną

Strony w Astro

aiact.waw.pl — case study strony w Astro

Statyczna strona w Astro 7: 108,5 KB przy pierwszym wejściu, 82 podstrony w 2,84 s builda i zero zewnętrznych domen. Decyzje, pomiary i ograniczenia tego podejścia.

Zaktualizowano 2026-09-02

aiact.waw.pl to statyczna strona zbudowana w Astro 7 dla usługi doprowadzania firm do zgodności z AI Act. Pierwsze wejście na stronę główną kosztuje 108,5 KB transferu, powrót — 27,9 KB. Przeglądarka nie odpytuje ani jednej zewnętrznej domeny, a 82 podstrony powstają w jednym buildzie trwającym poniżej trzech sekund.

Wszystkie liczby w tym artykule pochodzą z produkcyjnego builda repozytorium (commit 2a15b36, pomiar z 2 września 2026) i są podane po kompresji gzip, czyli tak, jak zasób jedzie po sieci.

Czego wymagał projekt

Strona ma jedno zadanie sprzedażowe — doprowadzić właściciela małej lub średniej firmy od pytania „czy AI Act mnie dotyczy" do umówionego terminu — i kilka wymagań, które przy typowym stosie technologicznym stoją ze sobą w konflikcie:

  • Formularz kwalifikujący i ankieta wyceny działające bez własnego backendu.
  • Kalendarz rezerwacji spotkań z realną blokadą terminu, odporną na dwa równoczesne kliknięcia.
  • Baza wiedzy: 66 artykułów w Markdown, każdy jako osobny adres do zaindeksowania.
  • Zero analityki, pikseli i cookies — na stronie sprzedającej zgodność z prawem to nie jest detal.
  • Wysoki wynik wydajności i dostępności jako wymóg briefu, nie miły dodatek.

Decyzje architektoniczne

WarstwaWybórDlaczego tak
FrameworkAstro 7, tryb output: staticzero JavaScriptu domyślnie, brak serwera aplikacji do utrzymania
Warstwa interaktywnawaniliowy TypeScript, bez integracji React/Vue/Sveltelicznik, zakładki i formularz nie uzasadniają kosztu frameworka w przeglądarce
Styleczysty CSS z custom properties, jeden plik tokenówpełna kontrola nad tym, ile bajtów CSS trafia do użytkownika
TypografiaOpen Sans 400/600/700, self-hosting, subsety latin i latin-extbrak zapytań do zewnętrznych domen, polskie znaki diakrytyczne komplet
Treśćjeden plik źródłowy dla copy, Content Layer dla 60 artykułów wikidane strukturalne budują się z tego samego źródła, więc nie rozjeżdżają się z treścią
HostingNetlify: statyczne pliki, formularze i funkcje na żądaniebrak serwera do aktualizowania, wdrożenie i cofnięcie wdrożenia w jednym kroku

Najważniejsza z tych decyzji jest druga. Dołożenie integracji React tylko po to, żeby użyć client:visible dla licznika i formularza, kosztowałoby dziesiątki kilobajtów przy interaktywności, którą obsługuje kilkaset linii własnego kodu. Mechanizm wysp opisujemy w artykule o architekturze wysp w Astro — tutaj wysp nie ma w ogóle, bo żadna nie była potrzebna.

Co strona faktycznie waży

Zasób strony głównejRozmiar po gzipUwagi
HTML razem z wbudowanym CSS i skryptami27,9 KBjeden dokument, brak osobnego pliku CSS blokującego render
JavaScript w osobnych plikach3,8 KBdwa moduły: wspólny szkielet strony i logika strony głównej
Fonty ładowane z wyprzedzeniem65,7 KBcztery pliki woff2: wagi 400 i 700, subsety latin i latin-ext
Logo i ikona strony11,2 KBWebP wybierany przez element picture, favicon jako SVG
Pierwsze wejście, razem108,5 KB11 zasobów, wszystkie z tej samej domeny
Kolejne wejście27,9 KBfonty i moduły JavaScript zostają w pamięci podręcznej

Podstrony bazy wiedzy są jeszcze lżejsze: mediana z 82 wygenerowanych dokumentów to 21,6 KB po gzip, najlżejszy ma 6,5 KB. Cały build — 82 strony wraz z mapą witryny — zajmuje 2,84 sekundy, co ma znaczenie przy każdym wdrożeniu i przy każdym pull requeście w CI.

Jak to wygląda w pomiarze zewnętrznym

PageSpeed Insights (Lighthouse 13.4.1, pomiar z 2 września 2026) daje stronie 100 punktów we wszystkich czterech kategoriach — wydajność, ułatwienia dostępu, sprawdzone metody i SEO — jednocześnie w wariancie mobilnym i desktopowym. Największy element treści renderuje się w 1,0 s na emulowanym telefonie z łączem 4G i w 0,4 s na komputerze, przy zerowym czasie blokowania wątku głównego.

Progi „dobrego" wyniku dla metryk Core Web Vitals to 2,5 s dla LCP, 200 ms dla INP i 0,1 dla CLS (web.dev/articles/vitals). Pełny odczyt, warunki pomiaru i zastrzeżenia co do interpretacji rozkładamy w artykule o wynikach PageSpeed Insights.

Czego na tej stronie świadomie nie ma

  • Frameworka UI w przeglądarce. Interaktywność to licznik, zakładki, dwuetapowy formularz i podgląd wzorów dokumentów — obsłużone własnym kodem na czystym DOM.
  • Frameworka CSS. Zamiast klas narzędziowych jeden plik tokenów: kolory, skala typograficzna, odstępy. Audyt kontrastu czyta ten sam plik, więc kontrola jakości patrzy dokładnie na te wartości, które renderuje przeglądarka.
  • Analityki, pikseli i banera cookies. Zero zewnętrznych domen oznacza brak skryptów trzecich stron rywalizujących o wątek główny i brak zgód do zbierania.
  • Obrazów w treści. Wzory dokumentów są wektorami wstawionymi w HTML, więc skalują się bez utraty ostrości i nie rezerwują miejsca po pobraniu, tylko od razu.

Co przejmuje hosting, a czego strona nie musi robić sama

Netlify serwuje gotowe pliki z sieci brzegowej i unieważnia pamięć podręczną przy każdym wdrożeniu, więc nie trzeba ręcznie wersjonować zasobów ani czyścić cache po publikacji (dokumentacja Netlify o cache). Wdrożenie jest atomowe: albo publikuje się cała nowa wersja, albo żadna.

Formularze zgłoszeniowe obsługuje mechanizm hostingu, który skanuje zbudowany HTML przy wdrożeniu — nie ma dla nich osobnego backendu. Jedyny fragment działający po stronie serwera to rezerwacja terminu spotkania: funkcja zapisuje termin operacją „tylko jeśli wolny", więc dwa kliknięcia w tej samej sekundzie kończą się jedną rezerwacją i czytelnym błędem dla drugiej osoby, zamiast dwóch spotkań na tę samą godzinę.

Jak pilnujemy, żeby to się nie rozjechało

  1. Każdy push i pull request uruchamia kontrolę typów oraz szablonów Astro.
  2. Ten sam workflow uruchamia audyt kontrastu WCAG i struktury dostępności — jeden nagłówek h1, brak przeskoków w hierarchii, etykiety pól, brak duplikatów identyfikatorów.
  3. Niezaliczona para kontrastu kończy build błędem, zamiast trafiać na produkcję.
  4. Zmiany dotykające układu weryfikujemy zrzutem ekranu, nie samym przeczytaniem CSS.
  5. Dolny próg testów mobilnych to 360 px szerokości — poniżej tego progu wychodzą błędy niewidoczne na desktopie.

Czego to podejście nie rozwiązuje

Statyczna strona nie zastąpi panelu redakcyjnego. Jeśli treść ma edytować kilka osób nietechnicznych codziennie, do tego samego Astro trzeba dołożyć headless CMS albo wybrać inne narzędzie — rozstrzygamy to w porównaniu Astro, WordPressa i Next.js.

Statyczne wyjście nie obsłuży też widoków zależnych od zalogowanego użytkownika. Tam, gdzie pojawia się konto, historia zamówień czy panel klienta, potrzebna jest warstwa serwerowa — albo w postaci pojedynczych funkcji, jak przy rezerwacji terminów, albo pełnej aplikacji.

Co z tego przenosimy do kolejnych projektów

  • Zacznij od budżetu transferu i traktuj każdą bibliotekę jak wydatek z tego budżetu.
  • Hostuj fonty u siebie i ładuj z wyprzedzeniem tylko te wagi, które widać na pierwszym ekranie.
  • Trzymaj treść w jednym źródle, z którego budują się też dane strukturalne.
  • Wpinaj audyt dostępności w CI, żeby regresja zatrzymywała się przed wdrożeniem.
  • Każdy skrypt zewnętrzny wprowadzaj jako świadomą decyzję kosztową, nie jako domyślny element strony.

Najczęściej zadawane pytania

Ile waży strona aiact.waw.pl?
Pierwsze wejście na stronę główną to 108,5 KB po gzip: 27,9 KB dokumentu z wbudowanym CSS, 3,8 KB skryptów, 65,7 KB fontów i 11,2 KB logo z ikoną. Kolejne wejście kosztuje 27,9 KB, bo fonty i skrypty zostają w pamięci podręcznej przeglądarki.
Czy statyczna strona obsłuży formularze i rezerwację terminu?
Tak. Zgłoszenia z formularzy przyjmuje mechanizm hostingu, który skanuje zbudowany HTML przy wdrożeniu, więc nie trzeba własnego backendu. Rezerwacja terminu działa jako pojedyncza funkcja serwerowa zapisująca slot operacją „tylko jeśli wolny", co wyklucza dwie rezerwacje na tę samą godzinę.
Dlaczego w projekcie nie ma Reacta ani innego frameworka UI?
Interaktywność sprowadza się do licznika, zakładek, dwuetapowego formularza i podglądu dokumentów. Dołożenie integracji frameworka kosztowałoby dziesiątki kilobajtów w przeglądarce, a te funkcje obsługuje kilkaset linii własnego kodu na czystym DOM.
Czy taką stronę da się rozbudowywać o kolejne podstrony?
Tak. Obecny build generuje 82 strony w 2,84 sekundy, a mapa witryny powstaje automatycznie przy każdym wdrożeniu. Artykuły bazy wiedzy leżą jako pliki Markdown w kolekcji treści, więc dodanie kolejnego nie wymaga zmian w kodzie komponentów.
Czy brak analityki nie utrudnia oceny skuteczności strony?
To świadomy kompromis: strona sprzedająca zgodność z prawem nie zbiera danych ani zgód. Skuteczność da się mierzyć po stronie serwera lub narzędziem bez cookies, ale każde takie rozwiązanie trzeba wtedy policzyć w budżecie transferu i opisać w polityce prywatności.