Przejdź do treści

Architektura wysp i selektywna hydratacja w frameworku Astro

Poznaj zasady działania architektury wysp i koncepcji braku kodu JavaScript na starcie. Sprawdź jak Astro rewolucjonizuje wydajność nowoczesnych stron internetowych.

Maciej Sala

Founder StriveLab

9 min czytaniaOpublikowano 24 kwietnia 2026 (Aktualizacja 25 maja 2026)

Architektura wysp to konkretny wzorzec, który zmienia sposób ładowania i uruchamiania strony w przeglądarce. Astro zbudowało wokół niego swoją strukturalną przewagę — i to właśnie dlatego strona Astro może domyślnie ładować się błyskawicznie, bez dodatkowych optymalizacji.

Skąd wzięła się Islands Architecture?

Pojęcie zostało ukute w 2019 roku przez Katie Sylor-Miller, frontend architekta Etsy, a później rozwinięte przez Jasona Millera (twórcę Preacta) w jego poście z 2020 roku. Idea jest pozornie prosta: renderuj stronę jako HTML na serwerze, a w obszarach, które faktycznie potrzebują interaktywności, umieść niezależne, samodzielne komponenty, które osobno.

W tradycyjnym podejściu (React, Vue, Angular, Svelte bez SvelteKit) cała aplikacja jest jedną dużą wyspą interaktywności. Przeglądarka dostaje pusty HTML albo HTML wyrenderowany na serwerze, potem pobiera paczkę JavaScriptu, uruchamia framework, odtwarza drzewo komponentów i dopiero wtedy strona zaczyna reagować na kliknięcia. Użytkownik odczuwa to jako sytuację: „strona już się pokazała, ale jeszcze nie działa".

Islands Architecture odwraca ten model — strona jest domyślnie statycznym HTML-em, a interaktywność to wyjątek, który aktywnie deklarujesz.

Jak Islands Architecture działa w Astro?

Weźmy typową stronę firmową mającą nagłówek z logo, hero, sekcję usług, formularz kontaktowy i stopkę. W tradycyjnym React/Next wszystkie te elementy są częścią aplikacji React, więc całe drzewo musi zostać zhydratowane, nawet jeśli interaktywny jest tylko formularz.

W Astro piszesz to tak:

Code
---
// src/pages/index.astro
import Header from '../components/Header.astro';
import Hero from '../components/Hero.astro';
import Services from '../components/Services.astro';
import ContactForm from '../components/ContactForm.tsx';
import Footer from '../components/Footer.astro';
---
 
<Header />
<Hero />
<Services />
<ContactForm client:visible />
<Footer />

Header, Hero, Services i Footer to komponenty .astrorenderują się na serwerze do czystego HTML-u i nie wysyłają do przeglądarki żadnego JavaScriptu związanego z tymi sekcjami. ContactForm to komponent React z dyrektywą client:visible; jego kod zostanie pobrany i uruchomiony dopiero wtedy, gdy użytkownik przewinie stronę do formularza.

W efekcie przeglądarka dostaje HTML, renderuje go natychmiast, a użytkownik widzi treść w ułamku sekundy. JavaScript ładuje się w tle, selektywnie, tylko tam, gdzie jest potrzebny.

Zero JS domyślnie w Astro: co to naprawdę znaczy?

W Next.js nawet strona, która wyświetla tylko statyczny tekst, ładuje runtime Reacta — reconciler, router oraz mechanizm hydratacji. W praktyce to 80–150 KB gzipped, zanim jakikolwiek Twój kod się wykonał. Dla porównania, w Astro strona bez interaktywnych komponentów to dosłownie 0 KB JavaScriptu.

Code
<!-- To jest cały HTML, który dostaje przeglądarka dla strony bez islands -->
<!doctype html>
<html lang="pl">
  <head>
    <meta charset="UTF-8" />
    <title>Strona główna</title>
    <link rel="stylesheet" href="/_astro/about.abc123.css" />
  </head>
  <body>
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  </body>
</html>

Żadnych skryptów , startu frameworka ani hydratacji komponentów — przeglądarka pobiera HTML, parsuje CSS i pokazuje stronę. W wypadku Lighthouse często oznacza to wynik Performance 95-100 bez ciężkiej optymalizacji. Dla : bardzo niski koszt JavaScriptu, dobry punkt wyjścia pod i oraz mniej ryzyka po stronie . Dla : Google widzi treść od razu, bez czekania na renderowanie po stronie klienta.

Dyrektywy hydratacji w Astro jako kontrakt wydajności

Kiedy już jakiś komponent musi być interaktywny, Astro daje Ci precyzyjną kontrolę nad tym, kiedy dostanie swój JavaScript. Pięć dyrektyw, pięć różnych strategii:

  • client:load — hydratacja natychmiast po załadowaniu strony. Dla rzeczy krytycznych, ponad zagięciem.
  • client:idle — hydratacja, kiedy przeglądarka jest bezczynna (). Dla elementów ważnych, ale nie pilnych.
  • client:visible — hydratacja, kiedy komponent pojawia się w widocznym obszarze ekranu (). Dla elementów poniżej pierwszego ekranu.
  • client:media="{query}" — hydratacja tylko wtedy, gdy zapytanie media query pasuje. Dla UI przeznaczonego wyłącznie na mobile albo desktop.
  • client:only="{framework}" — komponent renderuje się tylko po stronie klienta, pomijając . Dla rzeczy zależnych od przeglądarki (np. window, localStorage).

Szczegółowo rozbieram każdą z nich w artykule o client directives w Astro.

Komponenty z różnych frameworków na jednej stronie Astro

Architektura wysp ma jeszcze jedną konsekwencję, która w praktyce okazuje się bardziej użyteczna, niż się wydaje na pierwszy rzut oka — każda wyspa jest niezależna, więc może być napisana w innym frameworku.

Code
---
import ReactCounter from '../components/ReactCounter.tsx';
import VueChart from '../components/VueChart.vue';
import SvelteForm from '../components/SvelteForm.svelte';
---
 
<ReactCounter client:load />
<VueChart client:visible />
<SvelteForm client:idle />

W tradycyjnej SPA takie połączenie byłoby trudne do utrzymania, bo framework jest zwykle jeden. W Astro każda wyspa ładuje tylko runtime swojego frameworka i żyje we własnej paczce kodu.

Kiedy to się przydaje? Gdy masz komponent z zewnętrznej biblioteki napisany w Svelte i nie chcesz przepisywać go na React albo gdy migrujesz projekt z Vue na React etapami. Możesz też używać gotowego widgetu z biblioteki headless UI w innej technologii albo gdy budujesz wspólny system komponentów dla kilku projektów opartych na różnych stosach technologicznych.

Server Islands i dynamiczne fragmenty statycznej strony

Kolejna ewolucja wzorca, dodana w Astro 5 i ustabilizowana w 6, to Server Islands. Działają odwrotnie niż klienckie wyspy: komponent nie renderuje się razem z główną stroną, tylko jego rendering jest odłożony i wykonywany po wysłaniu pierwszej odpowiedzi.

Code
---
// src/pages/product.astro
import ProductDetails from '../components/ProductDetails.astro';
import LiveInventory from '../components/LiveInventory.astro';
---
 
<ProductDetails />
 
<!-- Server Island - renderuje się osobno, nie blokuje głównej odpowiedzi -->
<LiveInventory server:defer>
  <div slot="fallback">Ładowanie stanu magazynu...</div>
</LiveInventory>

Użytkownik od razu dostaje statyczną stronę produktu z cache, a dynamiczny fragment (np. stan magazynu, rekomendacje albo koszyk) dociera osobnym żądaniem i wypełnia miejsce zastępcze, gdy jest gotowy. To łączy wydajność z dynamiką SSR bez hydratowania komponentu frameworka po stronie klienta. Astro nadal wstawia mały skrypt techniczny, który pobiera zawartość wyspy serwerowej.

Szerzej opisuję ten mechanizm w artykule o Server Islands w Astro.

Kiedy Islands Architecture realnie wygrywa?

Astro nie jest magicznym rozwiązaniem na wszystko. Architektura wysp może nam bardzo dużo dać, ale gdy spełnione są konkretne warunki:

  1. Strona jest głównie treścią. Blog, dokumentacja, strona firmowa, portfolio, landing page, sklep z prostym koszykiem. Tam, gdzie większość powierzchni to tekst, obrazy i linki, a interaktywność pojawia się tylko w kilku miejscach.
  2. Core Web Vitals są krytyczne. Jeśli walczysz o pozycje w Google, konwersję z mobile albo wydajność na słabszym sprzęcie, eliminacja runtime'u frameworka daje bardzo dużo.
  3. Masz kontrolę nad tym, co interaktywne. Kiedy sam decydujesz, co potrzebuje JS, a co nie, możesz wyciągnąć maksimum z architektury wysp.

Kiedy Islands Architecture nie pomaga?

I druga strona medalu:

  1. Aplikacja jest interaktywna w 80%+, czyli dashboard, panel admina, edytor, CRM, kalkulator finansowy z wieloma polami — tam, gdzie cała strona to interakcja, architektura wysp nie daje wiele. Wyspa to cała strona.
  2. Stan globalny jest konieczny. Jeśli wiele komponentów musi dzielić stan, np. koszyk, użytkownika albo preferencje UI, wyspy komplikują sprawę. Każda ma swój kontekst, a synchronizacja wymaga zewnętrznego magazynu stanu.
  3. Potrzebujesz frameworka fullstackowego. Routes, Server Actions, middleware, auth, websockety — w tym zakresie Next.js daje dużo więcej.

Porównanie obu podejść szerzej opisałem w artykule Astro.js vs Next.js — które narzędzie wybrać w 2026 roku?.

Praktyczne wskazówki dla projektowania wysp w Astro

Jeśli zaczynasz projekt w Astro, rekomenduję następujący sposób myślenia:

Zaczynaj od zera JS. Każdy komponent traktuj domyślnie jako .astro — po React/Vue/Svelte z dyrektywą hydratacji sięgaj dopiero wtedy, gdy naprawdę potrzebujesz stanu, zdarzeń lub efektów.

Wybieraj najmniej agresywną dyrektywę. client:visible powinien być domyślnym wyborem, a potem client:idle dla rzeczy ważnych, ale poniżej viewportu. client:load zostaw dla rzeczy, które muszą działać natychmiast (navbar z dropdownem, hero z CTA).

Nie zawijaj całego layoutu w React. To typowy błąd przy migracji z Next.js — programista przyzwyczajony do _app.tsx opakowuje wszystko w jeden komponent React. W Astro layout powinien być .astro, a Reacta używasz tylko w miejscach, które naprawdę potrzebują interakcji.

Unikaj mapowania dużych list do klienckich wysp. Jeśli masz 100 elementów i każdy jest osobną wyspą React, szybko wracasz do ciężkiego JavaScriptu. Lepiej zrobić jeden kontener-wyspę, który obsłuży listę po stronie klienta.

Pilnuj, żeby wyspy były niezależne. Każda wyspa ma własny kontekst i hydratuje się osobno. Jeśli próbujesz dzielić stan między dwiema wyspami przez React Context, to znak, że model nie jest dobrze dobrany. Rozwiązaniem jest albo zweryfikowanie, czy faktycznie potrzebujesz dwóch wysp, albo użycie Zustand lub .

Budżet JavaScriptu dla wysp Astro

Największy błąd w Astro to traktowanie client:* jak taki bajer, który można dopisać w różne miejsca bez myślenia o wydajności, ponieważ każda wyspa wnosi runtime frameworka, kod komponentu i potencjalnie zależności. To, ile JavaScriptu trafi do przeglądarki, zależy nie tylko od tego, czy w ogóle użyjesz wyspy, ale też od dyrektywy — client:load, client:idle i client:visible mają różne konsekwencje dla czasu ładowania i INP. Różnice między nimi w praktyce opisuję w artykule o dyrektywach klienckich w Astro.

Typ sekcjiDomyślna decyzjaDlaczego
Hero z tekstem i obrazem.astro, bez hydratacjiTreść i układ nie potrzebują JS
Formularz kontaktowyReact/Svelte z client:visible albo server actionInterakcja jest potrzebna dopiero przy sekcji formularza
Menu mobileMała wyspa z client:loadNawigacja musi działać od razu
Kalkulator cenyclient:idle lub client:visibleWażny, ale zwykle nie jest pierwszą interakcją
Opinie, logo, FAQStatyczny HTMLInteraktywność zwykle nie wnosi wartości

Islands Architecture a SEO

Z perspektywy SEO architektura wysp ma jedną fundamentalną zaletę: Google i inne roboty indeksujące dostają gotowy HTML bez zależności od JavaScriptu. Nie czekają na renderowanie po stronie klienta, nie przepalają dodatkowo crawl budgetu i nie muszą wyciągać metadanych z dynamicznego kodu. Wszystko, co powinno być zindeksowane, jest w HTML-u już w odpowiedzi serwera.

Dla rankingów oznacza to lepszy punkt startowy pod Core Web Vitals, czystsze dane uporządkowane i mniejsze ryzyko, że ważna treść nie zostanie zindeksowana. Dla / roboty dostają prostszy dokument HTML, z mniejszą liczbą skryptów i mniej złożoną hydratacją, co może pomagać w maszynowym rozumieniu treści. Nie traktowałbym tego jednak jako gwarancji cytowań.

Głębiej temat SEO w Astro rozbieram w osobnym artykule.

Audyt techniczny i optymalizacja pod kątem SEO i GEO.
Audyt techniczny SEO

Często zadawane pytania

Czy Islands Architecture to to samo, co Partial Prerendering w Next.js?

Nie. PPR w Next.js dzieli stronę na statyczną powłokę i dynamiczne fragmenty renderowane na serwerze, ale runtime Reacta nadal trafia do przeglądarki. W Astro wyspy eliminują runtime frameworka wszędzie, gdzie nie jest potrzebny — różnica leży po stronie klienta, nie tylko serwera i jest to fundamentalna różnica architektoniczna.

Czy wyspy mogą się ze sobą komunikować?

Tak, ale nie przez React Context ani Vue provide/inject. Komunikacja między wyspami odbywa się przez zewnętrzny store (nanostores, Zustand), zdarzenia na window albo parametry URL. Każda wyspa ma izolowany cykl życia — to świadoma decyzja projektowa Astro.

Ile wysp na stronie to za dużo?

Przy ponad 10–15 klienckich wyspach na jednej stronie warto zweryfikować, czy część nie powinna być jednym większym komponentem. Każda wyspa to osobna paczka kodu, osobny start i osobna hydratacja — koszt rośnie liniowo.

Czy mogę mieć React Context dzielone między wyspami?

Nie. Każda wyspa jest niezależna i izolowana — to gwarancja architektoniczna Astro. Dla globalnego stanu jedynym rozwiązaniem jest zewnętrzny store: nanostores (oficjalnie zalecane) albo Zustand.

Czy Server Islands wymagają Cloudflare?

Nie. Server Islands działają na każdym adapterze SSR: Node.js, Vercel, Netlify, Cloudflare, Deno. Wymagany jest adapter obsługujący on-demand rendering — konkretna platforma nie ma znaczenia.

O autorze

Maciej Sala

Maciej Sala — konsultant technologiczny produktów cyfrowych i web 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.

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

Skontaktuj się ze mną

Biblioteka wiedzy na temat Astro

Czytaj dalej

Zobacz więcej wpisów
Łączenie React Vue i Svelte w architekturze wysp Astro

Zero JavaScript by default to chwytliwy slogan. Architektura, którą on opisuje, to coś większego: cały projekt może być statycznym HTML, a interaktywność jest precyzyjnie rozmieszczonymi wyspami. Każda wyspa to niezależna jednostka z własnym frameworkiem, własnym cyklem hydratacji i własnym kosztem runtime. React, Vue, Svelte i Solid działają na jednej stronie, pod jedną konfiguracją Astro. To nie eksperyment, lecz strategia migracji i narzędzie dla organizacji, które nie mogą sobie pozwolić na przepisanie wszystkiego od zera.

Maciej Sala

Maciej Sala

Founder StriveLab

Astro vs Next.js w 2026: Porównanie frameworków

Astro czy Next.js? Wybór frameworka musi być dokładnie przemyślany, zanim pojawi się pierwszy commit. Jeśli stoisz przed takim właśnie wyborem, w tym artykule staram się wykazać, w jakich obszarach najlepiej sprawdza się Astro , a w jakich będzie dominował Next.js .

Maciej Sala

Maciej Sala

Founder StriveLab

Jak kontrolować JS w Astro? Dyrektywy klienta w praktyce

Oznaczanie wszystkich komponentów client:load w projektach Astro niweczy ich potencjał. W rezultacie strona, która powinna być wydajna jak samochód wyścigowy, zachowuje się jak tramwaj z lat 70. Dyrektywy hydratacji to kontrakt wydajnościowy, którego warunki bezpośrednio determinują wydajność aplikacji.

Maciej Sala

Maciej Sala

Founder StriveLab