Pre-rendering, Incremental Static Regeneration (ISR) w Next.js

Next.js to framework, który oferuje różne techniki renderowania stron, takie jak Server-Side Rendering (SSR), Static Site Generation (SSG), i Incremental Static Regeneration (ISR). W tym artykule skupimy się na jednej z najnowszych funkcji Next.js, która zyskuje na popularności — Incremental Static Regeneration (ISR). Zrozumienie, jak działa ISR, i jak wykorzystać go w swojej aplikacji, pomoże Ci stworzyć bardziej wydajne strony, które są dynamicznie aktualizowane, ale zachowują wszystkie zalety stron statycznych.

1. Co to jest ISR i jak działa w Next.js?

Incremental Static Regeneration (ISR)

ISR to technika w Next.js, która pozwala na regenerowanie statycznych stron w czasie rzeczywistym po ich początkowym wygenerowaniu. Dzięki ISR możesz generować statyczne strony, które są szybko ładowane, ale również umożliwiają aktualizowanie zawartości strony, nawet po jej opublikowaniu, bez konieczności pełnej rekompilacji całej witryny.

ISR jest szeroko stosowane w aplikacjach, które wymagają częstych aktualizacji treści (np. blogi, sklepy internetowe, strony z danymi na żywo), a jednocześnie chcesz zachować szybkość ładowania stron dzięki generowaniu ich statycznie.

Jak działa ISR?

W tradycyjnym podejściu do Static Site Generation (SSG), strony są generowane raz, w momencie budowania aplikacji. Jeśli zawartość strony zmienia się, należy przeprowadzić pełną rekompilację aplikacji. ISR wprowadza jednak mechanizm, który pozwala na regenerację pojedynczych stron w tle, bez konieczności rekompilacji całej aplikacji.

  • Generowanie strony: Kiedy użytkownik odwiedza stronę, która jeszcze nie została wygenerowana, Next.js generuje ją statycznie.
  • Określenie czasu odświeżania: Za pomocą revalidate, możemy ustalić, co jaki czas strona ma być regenerowana w tle, gdy użytkownik ją odwiedzi.

Korzyści ISR:

  • Szybkie ładowanie stron: Strony są statycznie generowane, więc są ładowane bardzo szybko.
  • Aktualizacja w tle: Strony mogą być regenerowane w tle na podstawie nowych danych, bez przerywania działania strony.
  • Elastyczność: Możesz ustalić, jak często strony mają być regenerowane, w zależności od rodzaju treści.

2. getStaticPaths i dynamiczne generowanie stron

W Next.js, jeśli mamy stronę, której zawartość zależy od zmiennych danych (np. blogi, artykuły), musimy użyć funkcji getStaticPaths w połączeniu z getStaticProps do dynamicznego generowania stron na podstawie danych dostępnych w momencie budowania aplikacji.

Co to jest getStaticPaths?

getStaticPaths to funkcja, która pozwala na dynamiczne generowanie stron statycznych na podstawie zmieniających się danych. Musisz ją wykorzystać, gdy masz stronę z wieloma dynamicznymi ścieżkami, takimi jak strony artykułów w blogu lub produkty w sklepie.

Jak działa getStaticPaths?

  • Określenie wszystkich dostępnych ścieżek: getStaticPaths zwraca listę wszystkich dostępnych ścieżek (np. identyfikatorów artykułów lub produktów).
  • Statyczne generowanie stron: Na podstawie tych ścieżek Next.js generuje statyczne strony, które będą dostępne w aplikacji.
  • Dynamiczne parametry URL: Dzięki getStaticPaths możemy tworzyć dynamiczne strony, gdzie ścieżka URL zawiera zmienne parametry (np. /blog/[id]).

Przykład zastosowania getStaticPaths:

Załóżmy, że tworzymy stronę bloga, która zawiera wiele postów. Każdy post ma unikalny identyfikator (np. /blog/1, /blog/2, itd.). W tym przypadku musimy użyć getStaticPaths do wygenerowania wszystkich stron z postami na podstawie dostępnych danych.

				
					// pages/blog/[id].js
import { useEffect } from 'react';

// Funkcja getStaticPaths zwraca listę dostępnych ścieżek dla stron blogowych
export async function getStaticPaths() {
  // Załóżmy, że mamy listę postów, którą pobieramy z API
  const res = await fetch('https://api.example.com/posts');
  const posts = await res.json();

  // Tworzymy listę wszystkich dostępnych ścieżek
  const paths = posts.map((post) => ({
    params: { id: post.id.toString() },  // id to zmienny parametr w URL
  }));

  return { 
    paths, 
    fallback: false,  // Można ustawić na true lub blocking w zależności od potrzeb
  };
}

// Funkcja getStaticProps generuje stronę statycznie dla konkretnego posta
export async function getStaticProps({ params }) {
  const { id } = params;
  const res = await fetch(`https://api.example.com/posts/${id}`);
  const post = await res.json();

  return {
    props: { post }, // Przekazujemy dane do komponentu
  };
}

const Post = ({ post }) => {
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  );
};

export default Post;

				
			

Jak działa ten kod?

  1. getStaticPaths: Pobieramy wszystkie dostępne posty z API i generujemy ścieżki URL dla każdego postu (/blog/[id]).
  2. getStaticProps: Dla każdej ścieżki, generujemy stronę postu na podstawie danych dostępnych w API. Te strony są statycznie generowane podczas budowania aplikacji.
  3. Dynamiczne ścieżki: Dzięki getStaticPaths tworzymy strony z dynamicznymi parametrami URL (np. /blog/1), które są statycznie generowane.

3. Regeneracja stron statycznych w czasie rzeczywistym (ISR)

Za pomocą ISR możemy określić, jak często konkretne strony mają być regenerowane. Możemy ustawić parametr revalidate, który określa, co ile sekund Next.js będzie próbował regenerować stronę w tle, gdy użytkownik ją odwiedzi.

Jak działa regeneracja stron w ISR?

  • revalidate: Parametr revalidate mówi Next.js, co ile sekund strona ma być regenerowana w tle, gdy użytkownik ją odwiedzi. Jeśli czas regeneracji minie, a ktoś wejdzie na stronę, Next.js zacznie ją regenerować.
  • Regeneracja w tle: Proces regeneracji strony odbywa się w tle, a użytkownik wciąż widzi wersję stronę, która została wcześniej wygenerowana, aż proces regeneracji zostanie zakończony.

Przykład z ISR:

Załóżmy, że mamy stronę produktu, która ma się odświeżać co 10 sekund, aby zaktualizować informacje (np. dostępność produktu).

				
					// pages/products/[id].js
import { useEffect } from 'react';

export async function getStaticPaths() {
  const res = await fetch('https://api.example.com/products');
  const products = await res.json();

  const paths = products.map((product) => ({
    params: { id: product.id.toString() },
  }));

  return { 
    paths, 
    fallback: true, 
  };
}

export async function getStaticProps({ params }) {
  const { id } = params;
  const res = await fetch(`https://api.example.com/products/${id}`);
  const product = await res.json();

  return {
    props: { product },
    revalidate: 10,  // Strona regeneruje się co 10 sekund
  };
}

const Product = ({ product }) => {
  return (
    <div>
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      <p>Price: {product.price}</p>
    </div>
  );
};

export default Product;

				
			

Jak działa ten kod?

  • revalidate: 10: Strona produktu jest generowana statycznie, ale będzie regenerowana w tle co 10 sekund, jeśli ktoś odwiedzi stronę.
  • Regeneracja w tle: Użytkownicy zobaczą starszą wersję strony, dopóki proces regeneracji nie zostanie zakończony. Po zakończeniu, nowa wersja strony będzie dostępna dla kolejnych użytkowników.

4. Przykłady zastosowania ISR

ISR jest idealnym rozwiązaniem dla stron, które:

  • Często się zmieniają, ale nie muszą być generowane na żądanie (np. blogi, sklepy internetowe, systemy zarządzania treścią).
  • Posiadają dużą liczbę stron, które mogą być generowane statycznie, ale wymagają odświeżania (np. artykuły, produkty).
  • Wymagają częstych aktualizacji, ale nie chcą poświęcać wydajności związanej z pełnym przetwarzaniem strony za każdym razem.

Typowe przypadki użycia ISR:

  • Sklepy internetowe, gdzie dostępność produktów zmienia się często.
  • Strony z wiadomościami lub artykułami, które muszą być regularnie aktualizowane.
  • Strony z dynamicznymi danymi, które są stale zmieniane, ale nie wymagają pełnej rekompilacji aplikacji.

Podsumowanie

Incremental Static Regeneration (ISR) to potężne narzędzie w Next.js, które pozwala na wygodne łączenie zalet stron statycznych (szybkość ładowania) z dynamicznością (aktualizacja treści w tle). Dzięki wykorzystaniu getStaticPaths, getStaticProps oraz mechanizmu revalidate, Next.js umożliwia tworzenie aplikacji, które są szybkie, ale również elastyczne i łatwe w utrzymaniu. ISR sprawia, że strony mogą być automatycznie aktualizowane, a użytkownicy zawsze widzą najnowszą wersję treści, bez konieczności przeładowywania całej aplikacji.