Introdução
Você percebeu que sua aplicação está travando em certos momentos ou apresentando baixo desempenho? Talvez usar Lazy Loading possa resolver seus problemas de performance.
Lazy Loading é uma estratégia de otimização de desempenho. Com essa estratégia, garantimos que alguns recursos sejam carregados somente quando realmente necessários, ou seja, quando estão prestes a entrar na área visível da página (viewport).
Visão geral
Por padrão, podemos usar Lazy Loading em JavaScript, CSS, fontes, imagens e iframes.
Podemos definir o atributo loading em elementos img ou iframe, assim:

Com isso, conseguimos instruir o navegador a adiar o carregamento desse elemento até que ele esteja prestes a ser exibido na tela.
Lazy Loading no Next.js
No Next.js, as coisas funcionam de forma um pouco diferente. Temos duas estratégias nativas principais para criar componentes com lazy loading, e vou adicionar mais uma que pode facilitar ainda mais nossa vida:
1. Dynamic Imports
Com os Dynamic Imports do Next.js, podemos importar componentes dinamicamente, algo muito útil para componentes que não são necessários no carregamento inicial da página.
Um bom exemplo de uso é com componentes de feedback, como modais ou alertas, que só são exibidos após alguma ação do usuário. Então, por que carregá-los logo no início?
Podemos importar apenas quando for realmente necessário!
Veja um exemplo onde temos um botão e um componente Snackbar do Material UI.
Após o clique, o Snackbar deve ser exibido com um aviso:

Resultado:

Podemos ver que o Snackbar e o Alert são carregados inicialmente, mas só são
utilizados se o usuário clicar no botão. E se ele não clicar? O
carregamento desses dois componentes se torna inútil.
Vamos olhar para o tamanho do Build, especialmente o "First Load JS":

Agora, o mesmo exemplo usando Dynamic Imports para Snackbar e Alert:

Resultado idêntico:

Build:

Podemos ver que o tamanho do First Load JS caiu significativamente!
- De
43 KBpara35.6 KB - E de
148 KBpara141 KB
Você pode pensar: “Mas foi pouco!”. Estamos falando de apenas uma página, com uma funcionalidade simples. Agora imagine isso em todo o seu site?
Vamos calcular o ganho total para 10 páginas:
-
Antes da otimização:
- Tamanho por página: 43 KB
- Total: 43 KB × 10 = 430 KB
-
Depois da otimização:
- Tamanho por página: 35.6 KB
- Total: 35.6 KB × 10 = 356 KB
Economia total
- Redução: 430 KB - 356 KB = 74 KB
- Porcentagem: (74 ÷ 430) × 100 ≈ 17,2%
Isso mostra que, em um site com muitas páginas, pequenas otimizações podem gerar uma grande diferença no consumo de recursos e no tempo de carregamento.
2. React Lazy
Também podemos usar o React.lazy, que é uma funcionalidade nativa do React
para importar componentes dinamicamente, bem parecido com os dynamic imports do
Next.js.
A diferença é que aqui, precisamos usar o Suspense para envolver o
componente, e passar um componente no fallback, que será exibido enquanto o
componente está sendo carregado.
Esse carregamento ocorre apenas na primeira vez que o componente é usado. Se o usuário recarregar a página, será carregado novamente, mas se ele continuar navegando, não haverá novo carregamento.
Exemplo:

Resultado:

Note que no primeiro clique no botão, apareceu "loading...", que é o componente definido no fallback.
Build:

Houve uma redução ainda maior do que com os Dynamic Imports do Next.js. Porém, há um componente de loading adicional, o que pode impactar na experiência do usuário (UX).
Por isso, essa abordagem deve ser alinhada com o time de design e produto, pois exibir um loading pode não ser uma boa ideia em alguns casos. É recomendável usar apenas quando o componente for realmente pesado ou a página estiver muito lenta.
3. React-Lazyload
O react-lazyload funciona de forma um pouco diferente. Ele não afeta
diretamente o carregamento inicial da página, mas sim monitora a posição dos
elementos em relação ao viewport.
Quando um elemento estiver próximo da tela, ele será renderizado.
Ou seja, podemos usá-lo para renderizar componentes pesados à medida que o usuário rola a página.
Exemplo:

Esse código gera 15 imagens. Imagine como seria pesado carregar todas de uma vez só? Com o Lazyload, as imagens são carregadas aos poucos, conforme o usuário rola a página.
Resultado:

Na aba “Network” do navegador, vemos que as imagens são carregadas à medida que são exibidas na tela.
Isso traz um grande ganho de performance, garantindo que a internet do usuário não fique sobrecarregada.
Conclusão
Vimos práticas valiosas para melhorar a performance da sua aplicação usando Lazy Loading com Next.js e React. Aprendemos que é possível carregar componentes, imagens e iframes apenas quando necessário, reduzindo consumo de recursos e acelerando o carregamento das páginas.
Espero que as explicações tenham sido claras. Qualquer dúvida, é só me chamar para conversar.
Fique com Deus e bons estudos!
Gostou do conteúdo? Aceito uma contribuição! :)
PIX: gabrielmonteiroduete@gmail.com
Aceito um café: ko-fi.com/gabrielduete (abre em nova aba)
Tem algo para acrescentar?
Esse blog é open source, então fique à vontade para abrir um PR no repositório. (abre em nova aba)
Me encontre também em:
- GitHub: @gabrielduete (abre em nova aba)
- LinkedIn: @gabrielduete (abre em nova aba)
- DEV: @gabrielduete (abre em nova aba)
- Tabnews: @gabrielduete (abre em nova aba)
- StackOverflow: @gabrielduete (abre em nova aba)
- Beecrowd: @gabrielduete (abre em nova aba)
- LeetCode: @gabrielduete (abre em nova aba)