É 2019! Todo mundo pensa que sabe a divisão de código. Então - vamos conferir!

O que significa divisão de código?
Em resumo, a divisão de código é quase não carregar uma coisa toda. Então você está lendo esta página e não precisa carregar um site inteiro. Quando você seleciona uma única linha de um banco de dados - não precisa pegar tudo.
Óbvio? A divisão de código também é bastante óbvia, não apenas sobre seus dados, mas sobre seu código.
Quem (o quê?) Está criando código dividido?
React.lazy
? Não - ele apenas usa. A divisão de código está sendo feita no nível do empacotador - webpack, pacote ou apenas seu sistema de arquivos no caso de módulos esm "nativos". A divisão de código é apenas arquivos, arquivos que você pode carregar em algum lugar "mais tarde". Então - para as perguntas " O que está alimentando a divisão de código? " - a resposta é - um "empacotador".
Quem (o que) está usando a divisão de código?
React.lazy
está usando. Basta usar a divisão de código do seu bundler. Apenas chamando import quando é renderizado. E isso é tudo.
O que é o React-loadable?
React.lazy
substituiu-o. E forneceu mais recursos, como Suspense
para controlar o estado de carregamento. Então - use React.Lazy
.
Sim, é tudo. Obrigado pela leitura e tenha um bom dia.
Por que o artigo não está terminado?
Bem. Existem algumas zonas cinzentas sobre React.lazy
e divisão de código que esqueci de mencionar.
Zona 1 cinza - teste
Não é fácil testar o React.lazy
devido à sua assincronidade . Seria apenas "vazio", desde que ainda não esteja carregado (mesmo que esteja) - Promises
e retornos de import
, e preguiçoso aceita promessas , que sempre são executadas no próximo tick .
Solução proposta? Você não acreditaria, mas a solução proposta é usar as tabelas síncronas - consulte solicitação de recebimento . Então - vamos fazer as nossas imports
sincrônicas !!! (para corrigir problemas preguiçosos nos testes ou em qualquer outro caso do lado do servidor)
const LazyText = lazy(() => ({ then(cb) { cb({default: Text});
Não é difícil converter a função de importação em uma tabela síncrona memorizada.
const syncImport = (importFn) => { let preloaded = undefined; const promise = importFn().then(module => preloaded = module);
Zona cinza 2 - SSR
Se você não precisa de SSR - continue lendo o artigo!
React.lazy
é compatível com SSR. Mas exige que o Suspense
funcione, e o Suspense NÃO é amigável para o servidor .
Existem 2 soluções:
Essa é uma boa opção, mas não seria muito amigável para o cliente. Porque Vamos definir a segunda solução possível:
- Use uma biblioteca especializada para rastrear scripts, pedaços e estilos usados e carregá-los no lado do cliente (especialmente estilos!) Antes de reagir à hidratação. Ou então - você faria buracos vazios em vez de seus componentes divididos por código. Mais uma vez - você não carregou o código que acabou de dividir, portanto, não pode renderizar o que deseja.
Veja as bibliotecas de divisão de código
- Componente universal - a biblioteca mais antiga e ainda atualizável. Ele "inventou" a divisão de código em termos de Webpack ensinado a dividir código.
- React-loadable - muito popular, mas uma biblioteca não mantida. Código feito cuspindo uma coisa popular. Os problemas estão fechados, portanto não há comunidade por perto.
- Componentes carregáveis - uma biblioteca completa de recursos, é um prazer usar, com a comunidade mais ativa do mercado.
- Componente importado - uma única biblioteca, não vinculada ao Webpack, ou seja, capaz de lidar com encomendas ou esm.
- React-async-component - biblioteca já inoperante (ainda popular), que causou um impacto significativo em tudo que envolve divisão de código, passagem de árvore React personalizada e SSR.
- Outra biblioteca - havia muitas bibliotecas, muitas das quais não sobreviveram à evolução do Webpack ou ao React 16 - eu não as listei aqui, mas se você conhece um bom candidato - apenas me DM.
Qual biblioteca escolher?
É fácil - não pode ser carregado por reação - é pesado, sem manutenção e obsoleto, mesmo que ainda seja mega popular. (e obrigado por popularizar a divisão do código, mais uma vez)
Componentes carregáveis - pode ser uma escolha muito boa. Está muito bem escrito, é mantido ativamente e suporta tudo pronto para uso. Suporte para "importações dinâmicas completas", permitindo importar arquivos dependendo dos acessórios fornecidos, mas, portanto, não tipáveis. Suporta Suspense, portanto, poderia substituir React.lazy.
Componente universal - na verdade "inventores" de importações dinâmicas completas - eles o implementaram no Webpack. E muitas outras coisas em nível baixo - eles fizeram isso. Eu diria - esta biblioteca é um pouco incondicional e um pouco menos amigável. A documentação dos componentes carregáveis é imbatível. Vale a pena usar essa biblioteca e ler a documentação - há muitos detalhes que você deve conhecer ...
Reagir-componente-importado - é um pouco estranho. É independente de empacotador, portanto nunca quebraria (não há nada a quebrar), funcionaria com o Webpack 5 e 55, mas isso tem um custo. Embora as bibliotecas anteriores durante o SSR adicionem todos os scripts usados ao corpo da página, você poderá carregar todos os scripts em paralelo - os arquivos importados não sabem os nomes dos arquivos e chamarão as "importações" originais (é por isso que o pacote independente) para carregar os pedaços usados, mas capaz de fazer chamadas apenas de dentro do pacote principal - para que todos os scripts adicionais sejam carregados somente após o download e a execução do principal. Não suporta importações dinâmicas completas, como React.lazy e, como resultado - tipificável. Também suporta Suspense. Usa tabelas de tempo síncronas no SSR. Ele também possui uma abordagem absolutamente diferente para CSS e suporte perfeito para renderização de fluxo.
Não há diferença de qualidade ou popularidade entre as bibliotecas listadas, e todos somos bons amigos - então escolha seu coração.
Zona cinza 3 - renderização híbrida
SSR é uma coisa boa, mas, você sabe, difícil. Projetos pequenos podem querer ter um SSR - há muitos motivos para tê-lo - mas eles podem não querer configurá-lo e mantê-lo.
SSR pode ser muito, MUITO difícil. Tente razzle ou vá com Next.js se você quiser uma vitória rápida.
Portanto, a minha solução mais fácil para SSR, especialmente para SPA simples, seria a pré-renderização. Como abrir seu SPA em um navegador e clicar no botão "Salvar". Como:
- React-snap - usa marionetista (também conhecido como Chrome sem cabeça) para renderizar sua página em um "navegador" e salva um resultado como uma página HTML estática.
- Rendertron - que faz o mesmo, mas de uma maneira diferente (em nuvem ).
A pré-renderização é "SSR" sem "Servidor". É SSR usando um cliente. Magia! E trabalhando fora da caixa ... ... ... ... mas não para cuspir código.
Então - você acabou de renderizar sua página em um navegador, salvou o HTML e pediu para carregar o mesmo material. Mas o código específico do servidor (para coletar todos os pedaços usados) não foi usado, pois NÃO HÁ SERVIDOR !

Na parte anterior, apontei as bibliotecas que são vinculadas ao webpack em termos de coleta de informações sobre os pedaços usados - eles não conseguiam lidar com a renderização híbrida.
A versão 2 dos componentes carregáveis (incompatível com a versão atual 5) foi parcialmente suportada pelo react-snap. O suporte foi embora.
O componente reagir-importado pode lidar com esse caso, desde que não esteja vinculado ao bundler / lado; portanto, não há diferença para SSR ou híbrido, mas apenas para reagir-snap, desde que ele suporte a "hidratação de estado", enquanto rendertron não.
Essa capacidade de reagir-componente importado foi encontrada durante a redação deste artigo, ela não era conhecida antes - veja o exemplo . É bem fácil
E aqui você precisa usar outra solução, que é perpendicular a todas as outras bibliotecas.
Reagir-componente pré-renderizado
Essa biblioteca foi criada para hidratação parcial e pode reidratar parcialmente o aplicativo, mantendo o restante ainda desidratado. E funciona para renderizadores SSR e Hybrid sem nenhuma diferença.
A ideia é simples:
- durante SSR - renderize o componente envolvido com um <div />
- no cliente - encontre essa div e use innerHTML até que o Component esteja pronto para substituir o HTML morto.
- você não precisa carregar e aguardar que um pedaço com componente dividido antes de
hydrate
NÃO torne um buraco branco em vez dele - basta usar HTML pré-renderizado, que é absolutamente igual ao que um componente real renderizaria e que já existe - ele vem com uma resposta do servidor (ou hídrica).
É por isso que precisamos aguardar o carregamento de todos os blocos antes de se hidratar - para corresponder ao HTML renderizado pelo servidor. É por isso que podemos usar pedaços de HTML renderizados pelo servidor até que o cliente não esteja pronto - é igual ao que apenas produziremos.
import {PrerenderedComponent} from 'react-prerendered-component'; const importer = memoizeOne(() => import('./Component'));
Há outro artigo sobre essa tecnologia , você pode ler. Mas o principal aqui - resolve o "Flash Of Unloaded Content" em outro, não muito comum para bibliotecas de divisão de código . Esteja aberto para novas soluções.
TLDR?
- não use react-loadable, não agregaria nenhum valor valioso
- React.lazy é bom, mas muito simples, ainda.
- SSR é uma coisa difícil, e você deve saber disso
- A renderização híbrida orientada por marionetistas é uma coisa. Às vezes, coisa ainda mais difícil.