Wstępne pobieranie tras w Next.js

Jak Next.js przyspiesza nawigację dzięki wstępnemu pobieraniu tras i jak go dostosować.

Czego się nauczysz?

Z tego artykułu dowiesz się, jak działa przekierowywanie w Next.js, jak jest ono optymalizowane pod kątem szybkości i jak je dostosować do swoich potrzeb.

Next.js nie musisz ręcznie konfigurować routingu. Next.js korzysta z przekierowywania opartego na systemie plików, co pozwala na tworzenie plików i folderów w katalogu ./pages/:

Zrzut ekranu pokazujący katalog stron zawierający 3 pliki: index.js, margherita.js i pineapple-pizza.js

Aby utworzyć link do różnych stron, użyj komponentu <Link> w podobny sposób jak starego elementu <a>:

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

Gdy używasz komponentu <Link> do nawigacji, Next.js robi dla Ciebie nieco więcej. Zwykle strona jest pobierana, gdy klikniesz link do niej, ale Next.js automatycznie pobiera z wyprzedzeniem kod JavaScript potrzebny do jej renderowania.

Gdy wczytasz stronę z kilkoma linkami, istnieje duże prawdopodobieństwo, że do czasu kliknięcia linku komponent, do którego prowadzi, został już pobrany. Dzięki temu aplikacja będzie szybciej reagować na Twoje działania, ponieważ szybciej będzie przełączać się na nowe strony.

W przykładowej aplikacji poniżej strona index.js zawiera link do strony margherita.js z użyciem elementu <Link>:

Użyj Narzędzi deweloperskich w Chrome, aby sprawdzić, czy margherita.js jest pobierane z poziomu pamięci podręcznej: 1. Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekran pełny ekran.

  1. Aby otworzyć Narzędzia dla programistów, naciśnij `Control+Shift+J` (lub `Command+Option+J` na Macu).
  2. Kliknij kartę Sieć.

  3. Zaznacz pole wyboru Disable cache (Wyłącz pamięć podręczną).

  4. Odśwież stronę.

Gdy wczytasz index.js, na karcie Sieć widać, że margherita.js została też pobrana:

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

Jak działa automatyczne pobieranie w tle

Next.js pobiera w poprzednim ładowaniu tylko linki, które pojawiają się w widoku, i wykorzystuje do ich wykrywania interfejs IntersectionObserver API. Wyłącza też pobieranie w tle, gdy połączenie z internetem jest powolne lub gdy użytkownicy mają włączone Save-Data. Na podstawie tych kontroli Next.js dynamicznie wstrzykuje tagi <link rel="preload">, aby pobrać komponenty na potrzeby kolejnych nawigacji.

Next.js tylko pobiera kod JavaScript, ale go nie wykonuje. W ten sposób nie pobiera żadnych dodatkowych treści, których może wymagać strona z zawczasu pobranymi treściami, dopóki nie klikniesz linku.

Unikaj niepotrzebnego pobierania w tle

Aby uniknąć pobierania niepotrzebnych treści, możesz wyłączyć wstępne pobieranie w przypadku rzadko odwiedzanych stron, ustawiając w elementach prefetch w elementach <Link> wartość false:

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

W tej drugiej przykładowej aplikacji strona index.js zawiera element <Link>, który prowadzi do strony pineapple-pizza.js, a element prefetch ma wartość false:

Aby sprawdzić aktywność sieci, wykonaj czynności opisane w pierwszym przykładzie. Gdy wczytasz index.js, na karcie Sieć w Narzędziach deweloperskich widać, że plik margherita.js został pobrany, ale pineapple-pizza.js nie:

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

Pobieranie w tle z wykorzystaniem kierowania niestandardowego

Komponent <Link> nadaje się do większości przypadków użycia, ale możesz też utworzyć własny komponent do zarządzania routingiem. Next.js ułatwia to dzięki interfejsowi router API dostępnemu w next/router. Jeśli chcesz coś zrobić (np. przesłać formularz) przed przejściem na nową trasę, możesz to zdefiniować w niestandardowym kodzie kierowania.

Gdy do routingu używasz komponentów niestandardowych, możesz też dodać do nich pobieranie w poprzedniości. Aby zaimplementować funkcję wstępnego pobierania w kodzie kierowania, użyj metody prefetch z useRouter.

W tej przykładowej aplikacji components/MyLink.js:

Wstępne pobieranie odbywa się w ramach haka useEffect. Jeśli właściwość prefetch obiektu <MyLink> ma wartość true, trasa określona we właściwości href jest pobierana wstępnie podczas renderowania obiektu <MyLink>:

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

Gdy klikniesz link, przekierowanie zostanie wykonane w handleClick. W konsoli odnotowywany jest komunikat, a metoda push przechodzi do nowej ścieżki określonej w metodzie href:

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

W tej przykładowej aplikacji strona index.js ma element <MyLink>, który prowadzi do elementów margherita.jspineapple-pizza.js. Właściwość prefetch ma wartość true w /margherita i false w /pineapple-pizza.

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

Gdy wczytasz index.js, na karcie Sieć widać, że plik margherita.js został pobrany, a plik pineapple-pizza.js nie:

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

Gdy klikniesz jeden z tych linków, Konsola zapisze w logach „Having fun with Next.js” i przejdzie do nowej ścieżki:

Konsola Narzędzi deweloperskich wyświetlająca komunikat „Having fun with Next.js”

Podsumowanie

Gdy używasz <Link>, Next.js automatycznie pobiera z wyprzedzeniem kod JavaScriptu potrzebny do renderowania połączonej strony, co przyspiesza przechodzenie do nowych stron. Jeśli korzystasz z rutowania niestandardowego, możesz użyć interfejsu API routera Next.js, aby samodzielnie zaimplementować wstępne pobieranie. Aby uniknąć niepotrzebnego pobierania treści, wyłącz prefetching w przypadku rzadko odwiedzanych stron.