Wstępne pobieranie tras w Next.js

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

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

W Next.js nie musisz ręcznie konfigurować routingu. Next.js używa routingu opartego na systemie plików, co pozwala po prostu tworzyć pliki i foldery w katalogu ./pages/:

Katalog Pages, który zawiera 3 pliki: index.js, margherita.js i pineapple-pizza.js.

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

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

Gdy do nawigacji używasz komponentu <Link>, Next.js wykonuje za Ciebie nieco więcej czynności. Zwykle strona jest pobierana po kliknięciu linku do niej, ale Next.js automatycznie pobiera z wyprzedzeniem JavaScript potrzebny do renderowania strony.

Gdy wczytujesz stronę z kilkoma linkami, prawdopodobnie zanim klikniesz link, komponent, do którego prowadzi, zostanie już pobrany. Zwiększa to szybkość działania aplikacji, ponieważ nawigacja do nowych stron jest szybsza.

W przykładowej aplikacji strona index.js zawiera link do strony margherita.js z elementem <Link>:

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

  1. Otwórz Narzędzia deweloperskie w Chrome.
  2. Kliknij kartę Sieć.
  3. Zaznacz pole wyboru Wyłącz pamięć podręczną.
  4. Odśwież stronę.

Gdy wczytasz index.js, na karcie Sieć zobaczysz, że pobrano też margherita.js:

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

Jak działa automatyczne pobieranie wstępne

Next.js wstępnie pobiera tylko linki, które pojawiają się w obszarze widocznym, i wykrywa je za pomocą interfejsu Intersection Observer API. Wyłącza też wstępne pobieranie, gdy połączenie sieciowe jest wolne lub gdy użytkownicy włączyli Save-Data. Na podstawie tych sprawdzeń Next.js dynamicznie wstawia tagi <link rel="preload">, aby pobrać komponenty na potrzeby kolejnych nawigacji.

Next.js tylko pobiera JavaScript, ale go nie wykonuje. Dzięki temu nie pobiera dodatkowych treści, o które może poprosić wstępnie pobrana strona, dopóki nie klikniesz linku.

Unikanie niepotrzebnego wstępnego pobierania

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

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

W tym drugim przykładzie aplikacji strona index.js ma <Link> do pineapple-pizza.js z ustawioną wartością prefetch na false:

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

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

Wstępne pobieranie z użyciem niestandardowego routingu

Komponent <Link> jest odpowiedni w większości przypadków użycia, ale możesz też utworzyć własny komponent do routingu. Next.js ułatwia to dzięki interfejsowi routera API dostępnemu w next/router. Jeśli chcesz wykonać jakąś czynność (np. przesłać formularz) przed przejściem do nowej trasy, możesz zdefiniować ją w kodzie routingu niestandardowego.

Jeśli używasz niestandardowych komponentów do routingu, możesz też dodać do nich wstępne pobieranie. Aby wdrożyć wstępne pobieranie w kodzie routingu, użyj metody prefetchuseRouter.

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

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

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

Gdy klikniesz link, przekierowanie nastąpi w handleClick. W konsoli zostanie zarejestrowany komunikat, a metoda push przejdzie 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 ma <MyLink> do margherita.jspineapple-pizza.js. Właściwość prefetch ma wartość true w przypadku /margherita i false w przypadku /pineapple-pizza.

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

Gdy wczytasz stronę index.js, na karcie Sieć zobaczysz, ż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, w konsoli pojawi się wpis „Having fun with Next.js.”, a następnie przejdziesz do nowej ścieżki:

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

Podsumowanie

Gdy używasz <Link>, Next.js automatycznie pobiera z wyprzedzeniem JavaScript potrzebny do renderowania połączonej strony, co przyspiesza przechodzenie do nowych stron. Jeśli używasz routingu niestandardowego, możesz samodzielnie zaimplementować wstępne pobieranie, korzystając z interfejsu API routera Next.js. Unikaj niepotrzebnego pobierania treści, wyłączając wstępne pobieranie w przypadku rzadko odwiedzanych stron.