Use React.lazy com confiança: Uma maneira segura de carregar componentes ao iterar rapidamente
React.lazy é uma ótima maneira de carregar componentes sob demanda e melhorar o desempenho do seu aplicativo. No entanto, às vezes pode levar a alguns problemas como "ChunkLoadError" e "Falha ao carregar o chunk".
O dilema
Hoje em dia, o desenvolvimento de software está se movendo mais rápido sob a filosofia popular de "mover-se rápido e quebrar as coisas". Sem julgamentos aqui - é assim que as coisas são. No entanto, esse ritmo rápido pode, às vezes, levar a problemas, especialmente quando se trata de carregar componentes no React.
Se você está trabalhando em um projeto que usa React.lazy para carregar componentes sob demanda, você pode ter encontrado alguns problemas como ChunkLoadError
e Falha ao carregar o chunk
. Aqui estão algumas razões possíveis:
- Há um problema de rede, por exemplo, a conexão de internet do usuário está lenta ou instável.
- O usuário está em uma versão obsoleta do aplicativo e o navegador está tentando carregar um chunk que não existe mais.
Normalmente, um simples refresh da página pode resolver o problema, mas não é uma ótima experiência para o usuário. Imagine se uma tela branca aparecer quando o usuário está navegando para outra rota - não é uma boa aparência para o seu aplicativo.
Podemos equilibrar a necessidade de velocidade com a necessidade de uma experiência suave para o usuário? Claro. Deixe-me mostrar como (com TypeScript, é claro).
A solução
Uma solução de força bruta pode ser salvar todas as versões dos chunks no servidor, eliminando assim o problema do "chunk ausente". À medida que seu aplicativo cresce, essa solução pode se tornar inviável devido às crescentes exigências de espaço em disco, e ainda assim não resolve o problema da rede.
Dado o fato de que uma tentativa ou um refresh pode resolver o problema, podemos implementar essas soluções em nosso código. Como o problema geralmente ocorre quando o usuário está navegando para outra rota, podemos resolvê-lo sem que o usuário perceba. Tudo o que precisamos fazer é criar um wrapper em torno da função React.lazy
que lidará com as tentativas e os refreshes.
Já existem alguns ótimos artigos sobre como implementar esse tipo de solução, então vou me concentrar na ideia e nos detalhes internos da solu ção.
Criar o wrapper
O primeiro passo é criar um wrapper em torno da função React.lazy
:
Lidar com as tentativas
Para problemas de rede, podemos lidar com as tentativas envolvendo a importFunction
em uma função tryImport
:
Parece simples, certo? Você também pode implementar o algoritmo de exponential backoff para lidar com as tentativas de maneira mais eficiente.
Lidar com os refreshes
Para o problema de versão obsoleta, podemos lidar com os refreshes capturando o erro e atualizando a página:
No entanto, essa implementação é muito perigosa, pois pode causar um loop infinito de refreshes quando o erro não pode ser resolvido por um refresh. Além disso, o estado do aplicativo será perdido durante o refresh. Portanto, precisamos da ajuda do sessionStorage
para armazenar a mensagem de que tentamos atualizar a página:
Agora, quando capturamos o erro da função safeLazy
, sabemos que é algo que não pode ser resolvido por um refresh.
Múltiplos componentes lazy na mesma página
Ainda há uma armadilha oculta na implementação atual. Se você tiver vários componentes lazy na mesma página, o loop infinito de refreshes ainda pode acontecer porque outros componentes podem redefinir o valor do sessionStorage
. Para resolver esse problema, podemos usar uma chave única para cada componente:
Agora, cada componente terá sua própria chave sessionStorage
e o loop infinito de refreshes será evitado. Podemos continuar ajustando a solução, por exemplo:
- Reunir todas as chaves em um array, assim, apenas uma chave de armazenamento é necessária.
- Configurar um limite de refresh para atualizar a página mais de uma vez antes de lançar um erro.
Mas acho que você entendeu a ideia. Uma solução abrangente em TypeScript com testes e configurações está disponível no repositório no GitHub. Também publiquei o pacote react-safe-lazy
no NPM, para que você possa usá-lo em seu projeto imediatamente.
Conclusão
O desenvolvimento de software é um trabalho delicado, e até os menores detalhes podem exigir esforço para serem resolvidos. Espero que este artigo possa ajudá-lo a lidar graciosamente com os problemas do React.lazy
e a melhorar a experiência do usuário do seu aplicativo.