Você não faz renderização no servidor, mas quer acelerar o desempenho do seu site que usa o React? Teste a pré-renderização.
O react-snap
é uma biblioteca de terceiros que pré-renderiza as páginas do seu site em arquivos HTML estáticos. Isso pode
melhorar os tempos de
Primeira exibição
no seu aplicativo.
Veja uma comparação do mesmo aplicativo com e sem a pré-renderização carregada em uma conexão 3G simulada e um dispositivo móvel:
Por que isso é útil?
O principal problema de desempenho em aplicativos grandes de página única é que o usuário precisa esperar que os pacotes JavaScript que compõem o site terminem o download para poder ver o conteúdo real. Quanto maiores os pacotes, mais tempo o usuário terá que esperar.
Para resolver isso, muitos desenvolvedores adotam a abordagem de renderizar o aplicativo no servidor em vez de apenas inicializá-lo no navegador. A cada transição de página/rota, o HTML completo é gerado no servidor e enviado ao navegador, o que reduz os tempos de primeira exibição, mas tem o custo de um tempo para primeiro byte mais lento.
A pré-renderização é uma técnica separada menos complexa que a renderização de servidor, mas que também oferece uma maneira de melhorar os tempos da primeira exibição no aplicativo. Um navegador headless ou sem interface do usuário é usado para gerar arquivos HTML estáticos de cada rota durante o tempo de build. Esses arquivos podem ser enviados com os pacotes JavaScript necessários para o aplicativo.
reação
react-snap
usa o Puppeteer para criar arquivos HTML pré-renderizados de diferentes rotas no aplicativo. Para
começar, instale-o como uma dependência de desenvolvimento:
npm install --save-dev react-snap
Em seguida, adicione um script postbuild
a package.json
:
"scripts": {
//...
"postbuild": "react-snap"
}
Isso executaria automaticamente o comando react-snap
sempre que um novo build dos
aplicativos fosse feito (npm build
).
A última coisa que você precisa fazer é alterar a forma como o aplicativo é inicializado.
Altere o arquivo src/index.js
para o seguinte:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
const rootElement = document.getElementById("root");
if (rootElement.hasChildNodes()) {
ReactDOM.hydrate(<App />, rootElement);
} else {
ReactDOM.render(<App />, rootElement);
}
Em vez de usar apenas ReactDOM.render
para renderizar o elemento raiz do React
diretamente no DOM, esse recurso verifica se algum nó filho já está presente
para determinar se o conteúdo HTML foi pré-renderizado (ou renderizado no
servidor). Se esse for o caso, ReactDOM.hydrate
será usado para anexar listeners
de eventos ao HTML já criado em vez de criá-lo novamente.
A criação do aplicativo agora vai gerar arquivos HTML estáticos como payloads para cada rota rastreada. Você pode conferir a aparência do payload HTML clicando no URL da solicitação HTML e na guia Previews no Chrome DevTools.
Flash de conteúdo sem estilo
Embora o HTML estático agora seja renderizado quase imediatamente, ele ainda permanece sem estilo por padrão, o que pode causar o problema de mostrar um "flash de conteúdo sem estilo" (FOUC, na sigla em inglês). Isso pode ser notado principalmente se você estiver usando uma biblioteca CSS-in-JS para gerar seletores, já que o pacote JavaScript terá que terminar a execução antes que qualquer estilo possa ser aplicado.
Para evitar isso, o CSS crítico ou a quantidade mínima de CSS necessária para a renderização da página inicial podem ser inline diretamente no <head>
do documento HTML. O react-snap
usa outra biblioteca de terceiros em segundo plano, a minimalcss
, para extrair qualquer
CSS crítico para diferentes rotas. É possível ativar isso especificando o
seguinte no seu arquivo package.json
:
"reactSnap": {
"inlineCss": true
}
A prévia da resposta no Chrome DevTools agora mostra a página estilizada com CSS essencial inline.
Conclusão
Se você não estiver renderizando rotas do lado do servidor no seu app, use
react-snap
para pré-renderizar o HTML estático para os usuários.
- Instale-o como uma dependência de desenvolvimento e comece apenas com as configurações padrão.
- Use a opção experimental
inlineCss
para CSS essencial inline se isso funcionar no seu site. - Se você estiver usando a divisão de código em um nível de componente em qualquer rota, tenha
cuidado para não pré-renderizar um estado de carregamento para seus usuários. O
README do
react-snap
(link em inglês) aborda isso em mais detalhes.