Wstępne pobieranie tras w Next.js

Jak Next.js przyspiesza nawigację dzięki wstępnemu pobieraniu tras i jak można je dostosować.

Czego się nauczysz?

Z tego posta dowiesz się, jak działa routing w Next.js, jak jest zoptymalizowany pod kątem szybkości i jak najlepiej go dostosować do swoich potrzeb.

W kodzie Next.js nie musisz ręcznie konfigurować routingu. Next.js wykorzystuje routing na podstawie systemu plików, co umożliwia tworzenie plików i folderów w katalogu ./pages/:

Zrzut ekranu z katalogiem stron zawierającym 3 pliki: index.js, margherita.js i anaapple-pizza.js.

Aby dodać linki do różnych stron, użyj komponentu <Link>, podobnie jak w przypadku starego elementu <a>:

<Link href="/margherita">
  <a>Margherita</a>
</Link>

Gdy używasz komponentu <Link> do nawigacji, Next.js robi za Ciebie nieco więcej. Normalnie strona jest pobierana, gdy klikasz do niej link, ale Next.js automatycznie pobiera z wyprzedzeniem kod JavaScript niezbędny do wyrenderowania strony.

Gdy wczytujesz stronę z kilkoma linkami, istnieje duże prawdopodobieństwo, że gdy klikniesz link, komponent, który za nią odpowiada, jest już pobrany. Poprawia to czas reagowania aplikacji, przyspieszając nawigację na nowe strony.

W poniższej przykładowej aplikacji strona index.js zawiera link do strony margherita.js z tagiem <Link>:

Użyj Narzędzi deweloperskich w Chrome, aby sprawdzić, czy tag margherita.js jest wstępnie pobrany: 1. Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację, a potem Pełny ekran pełny ekran.

  1. Naciśnij „Control + Shift + J” (lub „Command + Option + J” na Macu), aby otworzyć Narzędzia deweloperskie.
  2. Kliknij kartę Sieć.

  3. Zaznacz pole wyboru Wyłącz pamięć podręczną.

  4. Odśwież stronę.

Po załadowaniu pliku index.js na karcie Sieć widać, że pobierany jest też margherita.js:

Karta Network (Sieć) w Narzędziach deweloperskich z wyróżnionym plikiem margherita.js.

Jak działa automatyczne pobieranie z wyprzedzeniem

Next.js pobiera z wyprzedzeniem tylko linki, które pojawiają się w widocznym obszarze, i wykrywa je za pomocą interfejsu IntersectionObserver API. Wstępne pobieranie wyłącza też wtedy, gdy połączenie sieciowe jest powolne lub gdy użytkownicy mają włączoną funkcję Save-Data. Na podstawie tych testów Next.js dynamicznie wstrzykuje tagi <link rel="preload">, aby pobierać komponenty na potrzeby kolejnych nawigacji.

Next.js tylko pobiera kod JavaScript, ale nie wykonuje go. Dzięki temu do momentu kliknięcia linku nie pobierzemy żadnych dodatkowych treści, o które może poprosić pobrana z wyprzedzeniem strona.

Unikaj niepotrzebnego pobierania z wyprzedzeniem

Aby uniknąć pobierania niepotrzebnych treści, możesz wyłączyć pobieranie z wyprzedzeniem w przypadku rzadko odwiedzanych stron, ustawiając właściwość prefetch w <Link> na false:

<Link href="/pineapple-pizza" prefetch={false}>
  <a>Pineapple pizza</a>
</Link>

W tej drugiej przykładowej aplikacji strona index.js zawiera adres <Link>pineapple-pizza.js z parametrem prefetch ustawionym na false:

Aby sprawdzić aktywność w sieci, wykonaj czynności z pierwszego przykładu. Gdy załadujesz index.js, na karcie Sieć w Narzędziach deweloperskich zobaczysz, że pobrano margherita.js, ale pineapple-pizza.js nie:

Karta Network (Sieć) w Narzędziach deweloperskich z wyróżnionym plikiem margherita.js.

Pobieranie z wyprzedzeniem z routingiem niestandardowym

Komponent <Link> sprawdza się w większości przypadków, ale możesz też utworzyć własny komponent do routingu. Dzięki Next.js możesz to ułatwić dzięki interfejsowi API routera dostępnym w next/router. Jeśli przed przejściem na nową trasę chcesz coś zrobić (na przykład przesłać formularz), możesz to określić w niestandardowym kodzie trasy.

Jeśli do routingu używasz komponentów niestandardowych, możesz też dodać do nich pobieranie z wyprzedzeniem. Aby zaimplementować pobieranie z wyprzedzeniem w kodzie routingu, użyj metody prefetch z usługi useRouter.

Spójrz na aplikację components/MyLink.js w tej przykładowej aplikacji:

Wstępne wczytywanie odbywa się wewnątrz punktu zaczepienia useEffect. Jeśli właściwość prefetch w elemencie <MyLink> jest ustawiona na true, trasa określona we właściwości href zostanie pobrana z wyprzedzeniem podczas renderowania elementu <MyLink>:

useEffect(() => {
    if (prefetch) router.prefetch(href)
});

Gdy klikniesz link, routing zostanie wykonany w aplikacji handleClick. Komunikat jest rejestrowany w konsoli, a metoda push powoduje przejście do nowej trasy określonej w href:

const handleClick = e => {
    e.preventDefault();
    console.log("Having fun with Next.js.");
    router.push(href);
};

W tej przykładowej aplikacji strona index.js zawiera wartości od <MyLink> do margherita.js i pineapple-pizza.js. Właściwość prefetch jest ustawiona na true w systemie /margherita i na false w dniu /pineapple-pizza.

<MyLink href="/margherita" title="Margherita" prefetch={true} />
<MyLink href="/pineapple-pizza"  title="Pineapple pizza" prefetch={false} />

Gdy załadujesz index.js, na karcie Sieć będzie widać, że pobrano margherita.js, a pineapple-pizza.js nie:

Karta Network (Sieć) w Narzędziach deweloperskich z wyróżnionym plikiem margherita.js.

Gdy klikniesz dowolny z tych linków, konsola zarejestruje wpis „Zabawa z Next.js.” i przejdzie na nową trasę:

Konsola Narzędzi deweloperskich z wyświetlonym komunikatem „Zabawa z Next.js”.

Podsumowanie

Gdy używasz <Link>, Next.js automatycznie pobiera z wyprzedzeniem kod JavaScript potrzebny do renderowania powiązanej strony, co przyspiesza przechodzenie na nowe strony. Jeśli korzystasz z routingu niestandardowego, możesz samodzielnie wdrożyć pobieranie z wyprzedzeniem za pomocą interfejsu API routera Next.js. Aby uniknąć niepotrzebnego pobierania treści, wyłącz pobieranie z wyprzedzeniem w przypadku rzadko odwiedzanych stron.