Next.js stał się de facto standardem w budowaniu nowoczesnych aplikacji React, a dwa najważniejsze tryby renderowania – Incremental Static Regeneration (ISR) i Server‑Side Rendering (SSR) – często budzą wątpliwości przy wyborze architektury. W tym artykule przyjrzymy się ich wewnętrznym mechanizmom, zmierzymy rzeczywisty czas renderu, oszacujemy koszty zasobów oraz podpowiemy, kiedy warto wybrać jedno rozwiązanie nad drugim.
Jak działa Incremental Static Regeneration?
ISR łączy zalety statycznego generowania (SSG) z możliwością odświeżania treści po wdrożeniu. Podczas pierwszego żądania Next.js wygeneruje HTML i zapisze go w pamięci podręcznej (Edge lub CDN). Następnie, przy kolejnych żądaniach, serwer zwraca już zbuforowany plik, a w tle, jeśli upłynął revalidate określony w getStaticProps, uruchamia proces ponownego generowania.
export async function getStaticProps() {
const data = await fetchAPI();
return {
props: { data },
revalidate: 60 // odśwież co 60 s
};
}
Mechanizm opiera się na funkcji unstable_revalidate (od Next.js 13) lub wewnętrznej kolejce wywołań Lambda/Edge. Dzięki temu nie musimy trzymać całego serwera w stanie gotowości – jedynie krótką funkcję generującą nową wersję strony.
Server‑Side Rendering – klasyka z nowoczesnym cache'em
SSR renderuje stronę przy każdym żądaniu, wywołując getServerSideProps. Wynik jest przesyłany bezpośrednio do przeglądarki, a następnie React „hydratuje” interaktywny UI. W praktyce SSR wymaga stałego procesu Node.js, co wiąże się z większym zużyciem pamięci i CPU.
export async function getServerSideProps(context) {
const data = await fetchAPI(context.params.id);
return { props: { data } };
}
Wydajność SSR można podnieść, stosując warstwę cache (np. stale‑while‑revalidate w Vercel Edge) lub memoizację zapytań, ale każdy request wciąż wymaga przetworzenia w Node.
Porównanie ISR i SSR w Next.js – czasy renderu i koszty
- Cold start ISR: pierwsze żądanie po deployu generuje HTML – koszt podobny do SSR, ale jednorazowy.
- Warm ISR: kolejne żądania zwracają statyczny plik z CDN – latencja 20‑40 ms przy globalnym rozproszeniu.
- SSR: każdy request wymaga pełnego przebiegu Node – typowo 120‑250 ms w zależności od złożoności zapytań.
- Koszty: ISR płaci jedynie za storage CDN i sporadyczne wywołania Lambda; SSR płaci za stałe uruchomione instancje (CPU, RAM) oraz transfer.
W praktyce różnice stają się krytyczne przy wysokim RPS (requests per second). Przy 10 000 RPS ISR może obsłużyć ruch przy minimalnych kosztach, podczas gdy SSR wymaga skalowania poziomego, co podnosi rachunek.
Kiedy używać ISR, a kiedy nie?
- ISR: treści zmieniające się rzadko (np. blog, katalog produktów), SEO‑ważne, ale tolerujące opóźnienie
revalidate. - SSR: dane wymagające natychmiastowej aktualizacji (np. koszyk, personalizacja po logowaniu), dynamiczne UI zależne od sesji.
Jeśli Twoja aplikacja wymaga mieszanki – można łączyć oba podejścia w jednym projekcie, definiując getStaticProps dla publicznych stron i getServerSideProps dla sekcji chronionych.
Pułapki migracji z SSR na ISR
Przejście nie jest trywialne. Najczęstsze problemy to:
- Zapomniane zależności od
req/resw kodzie – ISR nie ma dostępu do obiektu request. - Cache‑stale data – nieodświeżone dane po zmianie w bazie, jeśli
revalidatejest zbyt długi. - Brak obsługi nagłówków autoryzacji w CDN, co uniemożliwia serwowanie spersonalizowanych stron.
Rozwiązaniem jest wyodrębnienie logiki biznesowej do warstwy usług (np. mikroserwis), a w komponentach używać jedynie czystych danych.
„Nie chodzi o to, które podejście jest szybsze, lecz o to, które lepiej dopasowuje się do wymagań Twojego produktu.”
Praktyczna checklista migracji SSR → ISR
- Sprawdź, które strony nie potrzebują danych kontekstowych (session, auth).
- Zidentyfikuj punkty, w których używasz
req.headers– przenieś je do API routes. - Ustal rozsądny interwał
revalidatena podstawie częstotliwości zmian danych. - Wdroż testy wydajnościowe (k6, Artillery) przed i po migracji.
- Monitoruj cache miss‑y w Vercel Analytics lub własnym Prometheus.
Typowe błędy i kompromisy architektoniczne
Wiele zespołów popełnia błąd „ISR‑by‑default”, co prowadzi do nieświadomego serwowania przestarzałych danych. Rozwiązaniem jest implementacja webhooków, które wywołują unstable_revalidate po każdej modyfikacji w bazie.
Inny kompromis to nadmierne poleganie na CDN‑cache przy dynamicznych komponentach. W takich przypadkach warto rozdzielić część UI na client‑side rendering (CSR) i pozostawić statyczny szkielet wygenerowany przez ISR.
Podsumowując, wybór między Next.js Incremental Static Regeneration a SSR powinien opierać się na analizie częstotliwości zmian treści, wymagań SEO oraz prognozowanego obciążenia. Dzięki świadomej strategii cache'owania i odpowiedniej segmentacji kodu, można osiągnąć znaczące oszczędności kosztowe i poprawić doświadczenie użytkownika.
Jeśli potrzebujesz pomocy przy optymalizacji architektury Next.js lub migracji SSR → ISR, nasz zespół w Coderia.it chętnie wesprze Twój projekt – skontaktuj się z nami już dziś.



