Não quer usar a renderização do lado do servidor, mas ainda quer acelerar o desempenho do seu site React? Tente fazer a pré-renderização.
react-snap
é uma biblioteca
de terceiros que pré-renderiza páginas do seu site em arquivos HTML estáticos. Isso pode
melhorar
o tempo de
First Paint
no seu app.
Confira 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 com aplicativos de página única grandes é que o usuário precisa esperar que os pacotes de JavaScript que compõem o site terminem de ser transferidos antes de poder acessar o conteúdo real. Quanto maiores os pacotes, maior será o tempo de espera do usuário.
Para resolver isso, muitos desenvolvedores usam a abordagem de renderizar o aplicativo no servidor em vez de apenas inicializá-lo no navegador. Com cada transição de página/rota, o HTML completo é gerado no servidor e enviado para o navegador, o que reduz os tempos de primeira pintura, mas tem o custo de um tempo mais lento para o primeiro byte.
A pré-renderização é uma técnica separada que é menos complexa do que a renderização do servidor, mas também oferece uma maneira de melhorar os tempos de First Paint no aplicativo. Um navegador sem cabeça, 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.
react-snap
O react-snap
usa o Puppeteer para
criar arquivos HTML pré-renderizados de rotas diferentes 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
ao 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 é mudar a forma como o aplicativo é inicializado.
Mude 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, ele verifica se algum nó filho já está presente
para determinar se o conteúdo HTML foi pré-renderizado (ou renderizado no
servidor). Nesse caso, ReactDOM.hydrate
é usado para anexar listeners de eventos
ao HTML já criado em vez de criar um novo.
A criação do aplicativo agora vai gerar arquivos HTML estáticos como payloads para cada rota rastreada. Para conferir o payload do HTML, clique no URL da solicitação HTML e, em seguida, na guia Previews no Chrome DevTools.
Flash de conteúdo sem estilo
Embora o HTML estático agora seja renderizado quase imediatamente, ele ainda não tem estilo por padrão, o que pode causar o problema de mostrar um "flash de conteúdo sem estilo" (FOUC). Isso pode ser especialmente perceptível 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 os estilos possam ser aplicados.
Para evitar isso, o CSS crítico, ou a quantidade mínima de CSS necessária
para renderizar a página inicial, pode ser inserido diretamente no <head>
do documento HTML. O react-snap
usa outra biblioteca de terceiros, minimalcss
, para extrair qualquer CSS crítico para rotas diferentes. Para ativar esse recurso, especifique o
seguinte no arquivo package.json
:
"reactSnap": {
"inlineCss": true
}
A visualização de resposta no Chrome DevTools agora mostra a página estilizada com o CSS crítico inline.
Conclusão
Se você não estiver renderizando rotas no servidor no seu aplicativo, use
react-snap
para pré-renderizar HTML estático para os usuários.
- Instale como uma dependência de desenvolvimento e comece com as configurações padrão.
- Use a opção experimental
inlineCss
para inline CSS crítico, se funcionar para 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 os usuários. O
react-snap
README aborda isso com mais detalhes.