Pełne nie jest jedyną odpowiedzią na pojedynczy dynamiczny element. Server Islands zachowują statyczny szkielet strony, a na żądanie generują jedynie wybrane fragmenty. Korzyść pojawia się wtedy, gdy większość strony rzeczywiście może być współdzielona przez użytkowników.
Czym są Server Islands w Astro?
Server Island to komponent Astro renderowany na żądanie poza głównym przebiegiem renderowania strony. Początkowa odpowiedź zawiera HTML strony, niewielki skrypt i opcjonalny . Strona może być prerenderowana, ale nie musi — server:defer działa również na trasie renderowanej na żądanie. Po załadowaniu strony skrypt wysyła osobne żądanie, pobiera HTML komponentu i zastępuje nim fallback.
Server Island zwraca HTML z serwera. Dyrektywy hydratują komponent frameworka w przeglądarce i służą do interaktywności. server:defer służy do opóźnionego renderowania serwerowego. Jeśli fragment ma przyciski, lokalny stan lub animacje sterowane JavaScriptem, wewnątrz wyspy nadal może być potrzebna osobna wyspa kliencka.
Komponent serwerowy może czytać Astro.cookies, korzystać z Astro.request, odpytywać bazę i używać sekretów środowiskowych. Każde wywołanie pozostaje jednak publicznym żądaniem HTTP, dlatego kod musi walidować sesję, uprawnienia, parametry oraz błędy usług zależnych.
Kiedy Server Islands w Astro mają największy sens?
Rozwiązanie sprawdza się, gdy dynamiczny fragment jest niewielki i nie musi znaleźć się w początkowym HTML-u.
Karta produktu ze stanem magazynowym. Opis, zdjęcia i specyfikacja mogą być statyczne, a dostępność pobierana osobno. Ostateczną dostępność i cenę trzeba ponownie sprawdzić przy dodawaniu do koszyka lub składaniu zamówienia.
Blog ze spersonalizowanym paskiem użytkownika. Treść artykułu pozostaje statyczna, natomiast avatar oraz menu zależą od sesji. Odpowiedzi tego fragmentu nie mogą trafić do współdzielonego cache.
Rekomendacje zależne od profilu czytelnika. Artykuł jest wspólny dla wszystkich, a sekcja „Polecane dla Ciebie” powstaje na podstawie bieżącej sesji. Fallback może pokazać popularne materiały dostępne bez personalizacji.
W tych przypadkach główna treść może być dostarczana jako statyczny zasób CDN, a fragment dynamiczny dociera później. To wszystko nie oznacza automatycznie niższego kosztu, ponieważ każda odsłona może uruchamiać funkcję serwerową dla każdej niecachowanej wyspy.
Podstawowa konfiguracja Server Islands
Server Islands są stabilną funkcją Astro i w aktualnym Astro 7.1 nadal korzystają z dyrektywy server:defer. Projekt potrzebuje adaptera obsługującego renderowanie na żądanie. Sama strona może pozostać prerenderowana.
Po dodaniu adaptera uruchom build oraz środowisko zbliżone do produkcji. Czysty hosting plików statycznych nie ma procesu, który mógłby obsłużyć endpoint wyspy.
Kolejny krok to po prostu dodanie do wybranego komponentu dyrektywy server:defer:
Zobaczmy, jak może wyglądać sam komponent takiej wyspy:
Astro wymaga wykonywania przekierowań na poziomie strony, a nie wewnątrz komponentu potomnego. W związku z tym, Server Island powinna więc wyrenderować odpowiedni wariant fragmentu, np. link logowania dla anonimowej osoby. Operacje modyfikujące stan, takie jak wylogowanie, należy realizować metodą POST i odpowiednio zabezpieczyć zgodnie z przyjętym modelem sesji, uwzględniając ochronę przed CSRF, jeśli wymaga tego mechanizm uwierzytelniania.
Fallback dla Server Islands i doświadczenie użytkownika
Fallback stanowi część początkowego kodu HTML i jest widoczny do momentu załadowania wyspy. W sytuacji, gdy nie zarezerwujesz dla niego odpowiedniej przestrzeni, jego późniejsza podmiana spowoduje przesunięcie treści na stronie, co pogorszy wskaźnik . Stan zastępczy powinien być również zrozumiały dla użytkownika, zwłaszcza gdy ładowanie trwa dłużej niż zwykle.
Fallback rezerwuje miejsce dla docelowego komponentu. Nie musi odwzorowywać go co do piksela, ale powinien posiadać zbliżone minimalne wymiary:
Podobnie sprawa wygląda w przypadku tzw. skeletonów (ekranów szkieletowych):
A tak może wyglądać CSS dla skeletonu bez zależności od frameworka:
Przy komunikatach tekstowych warto stosować aria-live="polite", jednak dekoracyjny szkielet ładowania (skeleton) nie powinien być wielokrotnie odczytywany przez czytnik ekranu. Pamiętaj też, aby przetestować działanie aplikacji w warunkach wolnego połączenia oraz pod kątem błędów endpointu – nie ogranicziaj się wyłącznie do szybkiego środowiska lokalnego.
Jak Server Islands działają pod maską?
Cały proces renderowania strony z użyciem Server Islands w Astro przebiega w czterech krokach:
- Podczas buildu komponent z
server:deferzostaje wydzielony do specjalnej trasy obsługiwanej przez adapter. - W początkowym HTML-u Astro umieszcza fallback i mały skrypt odpowiedzialny za pobranie fragmentu.
- Po załadowaniu strony przeglądarka wysyła osobne żądanie dla każdej wyspy.
- Endpoint renderuje komponent do HTML-u, a skrypt zastępuje nim fallback.
Z perspektywy przeglądarki przypomina to następujący scenariusz:
są serializowane, szyfrowane kluczem buildu i przekazywane w parametrze żądania, co chroni przed przypadkowym odczytaniem wartości w adresie. Szyfrowanie nie jest jednak modelem uprawnień ani ochroną przed ponownym użyciem poprawnego żądania.
- Przekazuj identyfikator zasobu, a wewnątrz wyspy ponownie sprawdź, czy bieżąca sesja może go odczytać.
- Nie przekazuj haseł, tokenów sesji, kluczy API ani danych, których komponent nie potrzebuje.
- Traktuj wygenerowany URL jako możliwy do ponownego użycia. Szyfrowanie nie blokuje replay poprawnego żądania.
- Publiczną odpowiedź można cachować zgodnie z
Cache-Control, ale dane zależne od użytkownika powinny miećprivatelubno-store.
Astro korzysta z żądania GET, dopóki zaszyfrowane propsy mieszczą się w praktycznym limicie 2048 bajtów. Po przekroczeniu tego limitu przechodzi na POST, co wyłącza typowe cache przeglądarki dla tego żądania. W związku z powyższym, przekazuj wyłącznie minimalne dane wejściowe, a większe obiekty pobieraj wewnątrz komponentu.
ASTRO_KEY przy rolling deployment
Domyślnie każdy build generuje nowy, losowy klucz szyfrujący dla propsów. Jeśli CDN wciąż serwuje plik HTML ze starszej wersji, a żądanie wyspy trafi już na nowy serwer, odszyfrowanie danych może się nie powieść. Problem ten występuje najczęściej przy wdrożeniach kroczących (rolling deployments) oraz w architekturze wieloregionowej.
Zapisz wynik jako sekret o nazwie ASTRO_KEY w środowisku budowania i udostępnij go wszystkim równolegle działającym instancjom. Pamiętaj, aby absolutnie nie commitować klucza do repozytorium. Rotację zaplanuj tak, aby pokrywała się z wygaśnięciem starej wersji HTML lub mechanizmem ochrony przed niespójnością wersji po wdrożeniu.
Referer pomaga, ale nie autoryzuje
Wewnątrz wyspy Astro.url i Astro.request.url wskazują specjalny endpoint, a nie stronę, która zainicjowała żądanie. Adres strony można odczytać z Referer, lecz nagłówek może być nieobecny i nie stanowi dowodu uprawnień. Preferuj jawny prop z potrzebnym identyfikatorem, a Referer wykorzystuj wyłącznie jako pomocniczy kontekst po sprawdzeniu pochodzenia.
Server Islands vs Partial Prerendering w Next.js
W Next.js 16 jest częścią opt-in Cache Components. Statyczny shell może zawierać granice Suspense, a zawartość dynamiczna jest renderowana w czasie żądania i przesyłana strumieniowo. Cache można stosować na poziomie funkcji lub komponentu przez use cache, więc wcześniejsze twierdzenie o wyłącznie całościowym cache było nieprawidłowe.
| Aspekt | Astro Server Islands | Next.js 16 Cache Components i PPR |
|---|---|---|
| Granica dynamiczna | Komponent z server:defer | Poddrzewo wewnątrz Suspense |
| Transport | Osobne żądanie HTTP uruchamiane przez przeglądarkę | Strumień w ramach żądania strony |
| Początkowy HTML | Strona i fallback wyspy | Statyczny shell i fallback granicy Suspense |
| Kontrola cache | Cache odpowiedzi endpointu wyspy | use cache, cacheLife, tagi i handlery cache |
| Koszt wielu granic | Dodatkowe żądanie dla każdej wyspy | Więcej fragmentów w jednym strumieniu odpowiedzi |
| Typowe zastosowanie | Strona treściowa z kilkoma fragmentami serwerowymi | Aplikacja React z mieszaną statyką i danymi runtime |
Astro może wcześniej wyświetlić statyczny dokument, ale sama wyspa zaczyna pobierać dane dopiero po załadowaniu w przeglądarce. Z kolei Partial Prerendering potrafi rozpocząć dynamiczne przetwarzanie już w momencie żądania strony i przesłać gotowy wynik razem z nią. Rzeczywisty rezultat zależy od opóźnienia sieci, lokalizacji funkcji, cache i kosztu zapytań, dlatego porównuj oba warianty pomiarami. Szerszy kontekst znajdziesz w porównaniu Astro i Next.js.
Przykład Server Islands: licznik komentarzy
Załóżmy, że artykuły są generowane statycznie, lecz licznik komentarzy ma być odświeżany częściej niż cały serwis. Pobranie licznika podczas buildu szybko się zestarzeje, a pobranie go w głównym renderze na żądanie zmieni model dostarczania całej strony. Server Island rozdziela oba cykle aktualizacji:
Limit czasu (timeout) ogranicza czas blokowania zasobów przez funkcję, ale nie gwarantuje wyświetlenia czytelnego błędu w przeglądarce. Z tego powodu fallback powinien być w pełni użyteczny także wtedy, gdy API całkowicie nie odpowiada. Jeśli dane mogą być nieaktualne przez minutę, ustaw odpowiedni nagłówek Cache-Control dla odpowiedzi komponentu (wyspy) i upewnij się na docelowym adapterze lub CDN-ie, czy odpowiedź rzeczywiście jest buforowana. Pamiętaj też, aby danych powiązanych z sesją użytkownika nigdy nie umieszczać we wspólnym, współdzielonym cache.
Ograniczenia i pułapki Server Islands
Propsy mają ograniczony zestaw obsługiwanych typów. Astro przyjmuje między innymi zwykłe obiekty, tablice, Map, Set, Date, URL i BigInt, ale odrzuca funkcje oraz cykliczne referencje.
Każda wyspa zwiększa liczbę żądań. Połącz fragmenty korzystające z tej samej sesji lub bazy, jeśli osobne endpointy nie dają korzyści cache albo niezależnego ładowania.
Kontekst strony nie przechodzi automatycznie. Wyspa działa w osobnym żądaniu, więc potrzebne dane przekaż jako małe propsy lub odtwórz z sesji.
Referer może być pusty lub zmieniony. Nie buduj na nim autoryzacji ani logiki, której brak nagłówka uniemożliwi działanie fragmentu.
Prywatna odpowiedź musi ominąć współdzielony cache. Użyj
privatelubno-storei sprawdź rzeczywiste nagłówki generowane przez adapter oraz platformę.Błąd wyspy nie blokuje zadania użytkownika. Dodaj timeouty, telemetrykę endpointu oraz fallback, który zachowuje sens przy awarii.
Dobre praktyki Server Islands: cache, prywatność i placeholdery
Projektuj osobno statyczny dokument, endpoint wyspy i fallback. Każda z tych warstw ma inne wymagania dotyczące świeżości, prywatności i awarii.
- Główny dokument zawiera treść wspólną i może być prerenderowany albo publicznie cachowany.
- Wyspa prywatna wyłącza współdzielony cache przez
Cache-Control: privatealbono-store. - Wyspa publiczna dostaje świadomy czas świeżości, na przykład , jeśli minuta opóźnienia jest akceptowalna.
- Małe propsy ograniczają adres i koszt. Przekazuj identyfikator zamiast kompletnego rekordu z bazy.
- Autoryzacja odbywa się podczas każdego wywołania. Nie ufaj temu, że prop został wcześniej zaszyfrowany.
- Fallback działa także podczas awarii. Nie ukrywaj w wyspie jedynej drogi do krytycznej funkcji strony.
Google potrafi renderować JavaScript, więc zawartość wyspy nie jest z definicji niewidoczna. Nadal zależy jednak od drugiego żądania, działania skryptu i dostępności endpointu, a nie każdy crawler wykonuje JavaScript. W związku z powyższym, główna odpowiedź na intencję strony i linki potrzebne do jej odkrywania powinny pozostać w początkowym HTML-u.
Server Islands a cache tras w Astro 7
Astro 7 wprowadziło własny mechanizm buforowania tras (route caching). Funkcje takie jak Astro.cache, routeRules czy provider cache służą do zapisywania odpowiedzi dla stron renderowanych na żądanie. Wymagają one skonfigurowania odpowiedniego dostawcy, a w trybie deweloperskim buforowanie jest domyślnie wyłączone. Strony prerenderowane są już w pełni statyczne, więc nie korzystają z tego mechanizmu.
Stabilna obsługa API nie oznacza jeszcze identycznego backendu cache na każdym hostingu. Wbudowany provider pamięciowy sprawdza się wyłącznie na pojedynczej instancji, z kolei dostawcy CDN w oficjalnych adapterach Cloudflare, Netlify czy Vercel wciąż mają status eksperymentalny. Przed wdrożeniem najlepiej dokładnie zweryfikować obsługę nagłówków, unieważniania oraz replikacji danych dla wybranego adaptera.
Oba mechanizmy rozwiązują różne problemy. Server Islands oddzielają dynamiczny fragment od dokumentu. Route caching ogranicza koszt ponownego renderowania tras, które obejmiesz jego konfiguracją. Możesz używać obu w jednym projekcie, ale cache głównej strony nie ustala automatycznie polityki cache odpowiedzi wyspy. Zachowanie sprawdzaj po astro build i astro preview, ponieważ cache tras jest wyłączony w trybie deweloperskim.
Wydajność Server Islands: kiedy to się opłaca?
Server Islands zwykle pomagają, gdy:
- Większość dokumentu jest wspólna dla wszystkich i może zostać prerenderowana.
- Dynamiczny fragment jest mały oraz niezależny od głównego zadania użytkownika.
- Statyczny HTML ma wysoki współczynnik trafień cache.
- Endpoint wyspy znajduje się blisko bazy lub usługi, z której pobiera dane.
Inny model może być prostszy, gdy:
- Prawie cała strona zależy od sesji i wymaga .
- Użytkownik musi zobaczyć dynamiczną treść przed wykonaniem pierwszego zadania.
- Wiele wysp wykonuje te same zapytania i tworzy kaskadę żądań.
- Prosta wyspa kliencka pobierająca JSON daje ten sam efekt bez generowania HTML-u na serwerze.
Mierz koszt całej ścieżki ładowania: TTFB dokumentu, czas odpowiedzi każdej wyspy, moment zastąpienia elementu zastępczego (fallbacku), CLS, liczbę wywołań funkcji oraz odsetek błędów. Szybki początkowy HTML to za mało, jeśli użytkownik musi długo czekać na fragment kluczowy dla interakcji.


