Pré-busca de rotas no Next.js

Como o Next.js acelera a navegação com o pré-carregamento de rotas e como personalizar essa funcionalidade.

O que você aprenderá?

Neste post, você vai aprender como o roteamento funciona no Next.js, como ele é otimizado para velocidade e como personalizá-lo para atender melhor às suas necessidades.

No Next.js, você não precisa configurar o roteamento manualmente. O Next.js usa o roteamento baseado no sistema de arquivos, que permite criar arquivos e pastas no diretório ./pages/:

Captura de tela do diretório de páginas que contém três arquivos: index.js, margherita.js e abacaxi-pizza.js.

Para vincular a páginas diferentes, use o componente <Link>, de forma semelhante a como você usaria o elemento <a>:

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

Quando você usa o componente <Link> para navegação, o Next.js faz um pouco mais por você. Normalmente, uma página é transferida por download quando você clica em um link, mas o Next.js faz o pré-carregamento automático do JavaScript necessário para renderizar a página.

Quando você carrega uma página com alguns links, é provável que, quando você clicar em um link, o componente por trás dele já tenha sido buscado. Isso melhora a capacidade de resposta do aplicativo, tornando a navegação para novas páginas mais rápida.

No exemplo de app abaixo, a página index.js tem um link para margherita.js com um <Link>:

Use o Chrome DevTools para verificar se o margherita.js está sendo pré-buscado: 1. Para visualizar o site, pressione View App. Em seguida, pressione Fullscreen tela cheia.

  1. Pressione "Control+Shift+J" (ou "Command+Option+J" no Mac) para abrir as Ferramentas do desenvolvedor.
  2. Clique na guia Rede.

  3. Marque a caixa de seleção Desativar cache.

  4. Recarregue a página.

Quando você carrega index.js, a guia Rede mostra que margherita.js também foi transferido por download:

Guia &quot;Rede&quot; do DevTools com margherita.js destacado.

Como a pré-busca automática funciona

O Next.js faz a pré-busca apenas dos links que aparecem na janela de visualização e usa a API Intersection Observer para detectá-los. Ele também desativa a pré-busca quando a conexão de rede está lenta ou quando os usuários têm o Save-Data ativado. Com base nessas verificações, o Next.js injeta dinamicamente tags <link rel="preload"> para fazer o download de componentes para navegações subsequentes.

O Next.js só busca o JavaScript, não o executa. Dessa forma, ele não faz o download de nenhum conteúdo adicional que a página pré-buscada possa solicitar até que você acesse o link.

Evite a pré-busca desnecessária

Para evitar o download de conteúdo desnecessário, desative a pré-busca para páginas raramente visitadas definindo a propriedade prefetch em <Link> como false:

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

Neste segundo app de exemplo, a página index.js tem um <Link> para pineapple-pizza.js com prefetch definido como false:

Para inspecionar a atividade de rede, siga as etapas do primeiro exemplo. Quando você carrega index.js, a guia Rede do DevTools mostra que margherita.js é transferido por download, mas pineapple-pizza.js não:

Guia &quot;Rede&quot; do DevTools com margherita.js em destaque.

Pré-busca com roteamento personalizado

O componente <Link> é adequado para a maioria dos casos de uso, mas você também pode criar seu próprio componente para fazer o roteamento. O Next.js facilita isso com a API do roteador disponível em next/router. Se você quiser fazer algo (por exemplo, enviar um formulário) antes de navegar para uma nova rota, defina isso no código de roteamento personalizado.

Ao usar componentes personalizados para roteamento, você também pode adicionar o pré-carregamento a eles. Para implementar o pré-carregamento no código de roteamento, use o método prefetch de useRouter.

Confira o components/MyLink.js neste app de exemplo:

A pré-busca é feita no hook useEffect. Se a propriedade prefetch em um <MyLink> for definida como true, a rota especificada na propriedade href será pré-buscada quando esse <MyLink> for renderizado:

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

Quando você clica no link, o roteamento é feito em handleClick. Uma mensagem é registrada no console, e o método push navega até a nova rota especificada em href:

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

Neste app de exemplo, a página index.js tem um <MyLink> para margherita.js e pineapple-pizza.js. A propriedade prefetch está definida como true em /margherita e como false em /pineapple-pizza.

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

Quando você carrega index.js, a guia Network mostra que margherita.js foi transferido por download, mas pineapple-pizza.js não:

Guia &quot;Rede&quot; do DevTools com margherita.js em destaque.

Quando você clica em qualquer um dos links, o console registra "Having fun with Next.js" e navega para a nova rota:

Console do DevTools mostrando a mensagem &quot;Se divertindo com o Next.js&quot;.

Conclusão

Quando você usa <Link>, o Next.js faz a pré-busca automática do JavaScript necessário para renderizar a página vinculada, o que torna a navegação para novas páginas mais rápida. Se você estiver usando o roteamento personalizado, poderá usar a API do roteador Next.js para implementar a pré-busca por conta própria. Evite o download de conteúdo desnecessariamente desativando a pré-busca de páginas raramente visitadas.