Mind Group Technologies Especialistas em Tecnologia

React foi desenvolvido para criar UI’s interativas que são declarativas, modulares e multiplataformas. Hoje, é um dos mais populares — se não o mais popular — Framework de JavaScript para escrever aplicações front-end performáticas. Desenvolvido inicialmente para criar SPAs (Aplicações de uma página), React é usado agora para fazer websites completos e até mesmo aplicações mobile. Veja neste artigo sobre Melhores Práticas e Estratégias para SEO para React em 2021.

Se você tem uma vasta experiência com desenvolvimento web e for para o React, irá perceber uma incrível quantidade do seu código HTML e CSS se transformando em JavaScript. Isso se dá pois o React não recomenda criar ou atualizar diretamente os elementos de UI, mas invés disso descrever o “estado” deles. React vai então atualizar a DOM para corresponder com esse estado da maneira mais eficiente possível.

Como resultado, todas as mudanças na UI ou na DOM devem ser feitas pela engine do React. Apesar de conveniente para os desenvolvedores, isso pode significar carregamentos mais longos para os usuários e mais trabalho para os motores de busca achar e indexar o conteúdo.

Neste artigo, nós vamos abordar desafios enfrentados enquanto fazíamos aplicativos e websites com desempenho de SEO, e nós vamos mostrar várias estratégias para vencê-los.

Como o Google rastreia e indexa páginas da web

O Google recebe mais de 90% de todas as pesquisas online. Vamos dar uma olhada em seu processo de rastreamento e indexação.

Este print tirado da Documentação do Google pode nos ajudar. Observe que este é um diagrama de blocos simplificado. O Googlebot real é muito mais sofisticado. 

Pontos a serem observados:

  1. O Googlebot mantém uma fila de rastreamento contendo todos as URLs necessárias para rastrear e indexar no futuro.
  2. Quando o rastreador está ocioso, ele seleciona o próximo URL da fila, faz uma solicitação e busca o HTML.
  3. Depois de analisar o HTML, o Googlebot determina se precisa buscar e executar JavaScript para renderizar o conteúdo. Se sim, o URL é adicionado a uma fila de renderização.
  4. Posteriormente, o renderizador busca e executa JavaScript para renderizar a página. Ele envia o HTML renderizado de volta para a unidade de processamento.
  5. A unidade de processamento extrai todas as URLs em tags <a> mencionados na página da web e os adiciona de volta à fila de rastreamento.
  6. O conteúdo é adicionado ao índice do Google.

Observe que há uma distinção clara entre o estágio Processing que analisa HTML e o estágio Renderer que executa JavaScript.

Essa distinção existe porque a execução de JavaScript é cara, visto que o Googlebots precisa examinar mais de 130 trilhões de páginas da web. Portanto, quando o Googlebot rastreia uma página da web, ele analisa o HTML imediatamente e, em seguida, coloca o JavaScript na fila para ser executado mais tarde. A documentação do Google menciona que uma página permanece na fila de renderização por alguns segundos, embora possa demorar mais.

Também vale a pena mencionar o conceito de Orçamento de Rastreamento. O rastreamento do Google é limitado pela largura de banda, tempo e disponibilidade das instâncias do Googlebot. Ele aloca um orçamento ou recursos específicos para indexar cada site. Se você estiver construindo um site grande com conteúdo pesado e com milhares de páginas (por exemplo, um site de E-commerce) e essas páginas usarem muito JavaScript para renderizar o conteúdo, o Google poderá ler menos conteúdo de seu site.

Observação: Você pode ler as diretrizes do Google para gerenciar seu orçamento de rastreamento aqui.

Por que otimizar o React para SEO é um desafio

Nossa breve visão geral do Googlebot, rastreamento e indexação apenas arranha a superfície. Ainda assim, os engenheiros de software devem identificar os problemas potenciais enfrentados pelos mecanismos de pesquisa ao tentar rastrear e indexar as páginas do React. Agora podemos dar uma olhada mais de perto no que torna o React SEO desafiador e o que os desenvolvedores podem fazer para abordar e superar alguns desses desafios.

Conteúdo vazio de primeira passagem

Sabemos que os aplicativos React dependem muito do JavaScript e costumam ter problemas com os mecanismos de pesquisa. Isso ocorre porque o React emprega um Modelo de shell para aplicativos por padrão. O HTML inicial não contém nenhum conteúdo significativo, e um usuário ou um bot deve executar JavaScript para ver o conteúdo real da página.

Essa abordagem significa que o Googlebot detecta uma página vazia durante a primeira passagem. O conteúdo é visto pelo Google apenas quando a página é renderizada. Isso atrasará a indexação de conteúdo ao lidar com milhares de páginas.

Tempo de carregamento e experiência do usuário

Buscar, analisar e executar o JavaScript leva tempo. Além disso, o JavaScript pode precisar fazer chamadas de rede para buscar o conteúdo, e o usuário pode precisar esperar um pouco antes de visualizar as informações solicitadas.

O Google estabeleceu um conjunto de Indicadores vitais da web relacionados à experiência do usuário, usados ​​em seus critérios de classificação. Um tempo de carregamento mais longo pode afetar a pontuação de experiência do usuário, fazendo com que o Google classifique um site mais baixo.

Revisamos o desempenho de sites em detalhes na seção a seguir.

Metadados da página

As tags <meta> são úteis porque permitem que o Google e outros sites de mídia social mostrem títulos, miniaturas e descrições apropriadas para as páginas. Mas esses sites contam com a tag <head> da página buscada para obter essas informações. Esses sites não executam JavaScript para a página de destino.

O React renderiza todo o conteúdo, incluindo metatags, no cliente. Como o shell do aplicativo é o mesmo para todo o site / aplicativo, pode ser difícil adaptar os metadados para páginas individuais.

Mapa do site

Um Mapa do site é um arquivo onde você fornece informações sobre as páginas, vídeos e outros arquivos do seu site e as relações entre eles. Mecanismos de busca como o Google leem esse arquivo para rastrear seu site de forma mais inteligente.

O React não tem uma maneira embutida de gerar mapas de sites. Se estiver usando algo como o React Router para lidar com o roteamento, você pode encontrar ferramentas que podem gerar um mapa do site, embora possa exigir algum esforço.

Outras considerações de SEO

Essas considerações estão relacionadas ao estabelecimento de boas práticas de SEO em geral.

  1. Tenha uma estrutura de URL ideal para dar aos humanos e aos mecanismos de pesquisa uma boa ideia sobre o que esperar da página.
  2. Otimizar o arquivo robots.txt pode ajudar os robôs de pesquisa a entender como rastrear páginas em seu site.
  3. Use um CDN para servir todos os ativos estáticos como CSS, JS, fontes etc. e use imagens responsivas para reduzir o tempo de carregamento.

Podemos resolver muitos dos problemas descritos acima usando renderização do lado do servidor (SSR) ou pré-renderização. Revisaremos essas abordagens a seguir.

React Isomórfico

A definição do dicionário de isomórfico é “correspondente ou semelhante na forma.”

Em termos do React, isso significa que o servidor tem uma forma semelhante ao cliente. Em outras palavras, você pode reutilizar os mesmos componentes React no servidor e no cliente.

Essa abordagem isomórfica permite que o servidor renderize o aplicativo React e envie a versão renderizada aos nossos usuários e mecanismos de pesquisa para que eles possam visualizar o conteúdo instantaneamente enquanto o JavaScript é carregado e executado em segundo plano.

Frameworks como Next.js ou Gatsby popularizaram essa abordagem. Devemos observar que os componentes isomórficos podem parecer substancialmente diferentes dos componentes React convencionais. Por exemplo, eles podem incluir código executado no servidor em vez do cliente. Eles podem até incluir segredos de API (embora o código do servidor seja retirado antes de ser enviado ao cliente).

Um ponto a ser observado é que essas estruturas abstraem muita complexidade, mas também introduzem uma forma opinativa de escrever código. Iremos nos aprofundar nas compensações de desempenho mais adiante neste artigo.

Também faremos uma análise de matriz para entender a relação entre os caminhos de renderização e o desempenho do site. Mas antes disso, vamos examinar alguns princípios básicos de medição de desempenho de sites.

Métricas de desempenho do site

Vamos examinar alguns dos fatores que os mecanismos de pesquisa usam para classificar sites.

Além de responder à consulta de um usuário com rapidez e precisão, o Google acredita que um bom site deve ter os seguintes atributos:

  • Deve carregar rapidamente.
  • Os usuários devem ser capazes de acessar o conteúdo sem muito tempo de espera.
  • Deve se tornar interativo com as ações do usuário desde o início.
  • Não deve buscar dados desnecessários ou executar códigos caros para evitar o esgotamento dos dados ou da bateria de um usuário.

Esses recursos mapeiam aproximadamente para as seguintes métricas:

  • TTFB: Tempo até o primeiro byte – o tempo entre o clique em um link e a chegada do primeiro bit de conteúdo.
  • LCP: Pintura com maior conteúdo – O momento em que o artigo solicitado se torna visível. O Google recomenda manter esse valor abaixo de 2,5 segundos.
  • TTI: Tempo para interação – O tempo em para uma página se tornar interativa (onde o usuário pode rolar, clicar, etc.)
  • Bundle size: Tamanho do pacote – O número total de bytes baixados e o código executado antes que a página se tornasse totalmente visível e interativa.

Iremos revisitar essas métricas para entender melhor como os vários caminhos de renderização podem afetar cada um deles.

A seguir, vamos entender os diferentes caminhos de renderização disponíveis para os desenvolvedores React.

Caminhos de renderização

Podemos renderizar um aplicativo React no navegador ou no servidor e produzir resultados variados.

Duas funções mudam significativamente entre os aplicativos renderizados do lado do cliente e do servidor, nomeados roteamento e divisão de código. Vamos dar uma olhada nisso abaixo.

Renderização do lado do cliente (CSR)

A renderização do lado do cliente é o caminho de renderização padrão para um React SPA. O servidor servirá um aplicativo shell que não contém nenhum conteúdo. Depois que o navegador baixa, analisa e executa as fontes JavaScript incluídas, o conteúdo HTML é preenchido ou renderizado.

A função de roteamento é controlada pelo aplicativo cliente gerenciando o histórico do navegador. Isso significa que o mesmo arquivo HTML é servido independentemente de qual rota foi solicitada, e o cliente atualiza seu estado de exibição após ser processado.

A divisão de código é relativamente direta. Você pode dividir seu código usando importações dinâmicas ou React.lazy de forma que apenas as dependências necessárias sejam carregadas com base na rota ou nas ações do usuário.

Se a página precisar buscar dados do servidor para renderizar conteúdo – digamos, um título de blog ou uma descrição de produto -, ela só pode fazer isso quando os componentes relevantes são montados e renderizados.

O usuário provavelmente verá um sinal ou indicador de “Carregando dados” enquanto o site busca dados adicionais.

Renderização do lado do servidor para conteúdo estático (SSRS)

Imagine um cenário em que precisamos gerar HTML rapidamente.

Por exemplo, se estivermos construindo uma calculadora online e o usuário fizer uma consulta do tipo /calculate/34+15 precisamos processar a consulta, avaliar o resultado e responder com o HTML gerado.

Nosso HTML gerado tem uma estrutura bastante simples e não precisamos do React para gerenciar e manipular o DOM depois que o HTML gerado é veiculado.

Portanto, estamos apenas servindo conteúdo HTML e CSS. Você pode usar o método renderToStaticMarkup para fazer isso.

O roteamento será inteiramente controlado pelo servidor, pois ele precisa recalcular o HTML para cada resultado, embora o cache de CDN possa ser utilizado para fornecer respostas mais rapidamente. Os arquivos CSS também podem ser armazenados em cache pelo navegador para carregamentos de página subsequentes mais rápidos.

Renderização do lado do servidor com reidratação (SSRH)

Imagine o mesmo cenário descrito acima, mas desta vez precisamos de um aplicativo React totalmente funcional no cliente.

Vamos realizar a primeira renderização no servidor e enviar de volta o conteúdo HTML junto com os arquivos JavaScript. O React hidratará a marcação renderizada pelo servidor e o aplicativo se comportará como um aplicativo CSR a partir deste ponto.

O React fornece métodos integrados para executar essas ações.

A primeira solicitação é tratada pelo servidor e as renderizações subsequentes são gerenciadas pelo cliente. Portanto, esses aplicativos são chamados de aplicativos React universais (renderizados no servidor e no cliente). O código para lidar com o roteamento pode ser dividido (ou duplicado) no cliente e no servidor.

A divisão de código também é um pouco complicada, pois o ReactDOMServer não oferece suporte ao React. preguiçoso, então você pode ter que usar algo como Componentes Carregáveis.

Também deve ser observado que o ReactDOMServer executa apenas uma renderização superficial. Em outras palavras, embora o método de renderização para seus componentes seja chamado, os métodos de ciclo de vida como componentDidMount não serão chamados. Portanto, você precisará refatorar seu código para fornecer dados aos seus componentes usando um método alternativo.

É aqui que estruturas como NextJS aparecem. Eles mascaram as complexidades associadas ao roteamento e divisão de código em SSRH e fornecem uma experiência de desenvolvedor mais suave.

Essa abordagem produz resultados mistos no que diz respeito ao desempenho da página, como veremos em breve.

Pré-renderização para conteúdo estático (PRS)

E se pudéssemos renderizar uma página da web antes que um usuário a solicite? Isso pode ser feito em tempo de construção ou dinamicamente quando os dados são alterados.

Podemos então armazenar em cache o conteúdo HTML resultante em um CDN e veiculá-lo muito mais rápido quando um usuário solicitar.

Isso é chamado de pré-renderização antes de renderizarmos o conteúdo, solicitação pré-usuário. Essa abordagem pode ser usada para blogs e aplicativos de e-commerce, uma vez que seu conteúdo normalmente não depende dos dados fornecidos pelo usuário.

Pré-renderização com Reidratação (PRH)

Podemos querer que nosso HTML pré-renderizado seja um aplicativo React totalmente funcional quando um cliente o renderizar.

Depois que a primeira solicitação for atendida, o aplicativo se comportará como um aplicativo React padrão. Este modo é semelhante ao SSRH, descrito acima, em termos de roteamento e funções de divisão de código.

Matriz de Desempenho

O momento que você estava esperando finalmente chegou. É hora de um confronto. Vamos ver como cada um desses caminhos de renderização afeta as métricas de desempenho da web e determinar o vencedor.

Nesta matriz, atribuímos uma pontuação a cada caminho de renderização com base em seu desempenho em uma métrica de desempenho. A pontuação varia de 1 a 5:

  • 1 = Insatisfatório
  • 2 = Fraco
  • 3 = Moderado
  • 4 = Bom
  • 5 = Excelente
 TTFB
Tempo até o primeiro byte
LCP
Pintura com maior conteúdo
TTI
Tempo para interação
Bundle Size
Tamanho do pacote
Total
CSR5 – HTML pode ser armazenado em cache em um CDN1 – Várias viagens ao servidor para buscar HTML e dados2 – Busca de dados + atrasos na execução de JS2 – Todas as dependências de JS precisam ser carregadas antes da renderização10
CSRB4 – HTML pode ser armazenado em cache, uma vez que não depende de dados solicitados3 – Os dados são carregados com o aplicativo3 – JS deve ser buscado, analisado e executado antes da interação2 – Todas as dependências JS precisam ser carregadas antes da renderização12
SSRS3 – HTML é gerado em cada solicitação e não armazenado em cache5 – Sem carga útil JS ou operações assíncronas5 – A página é interativa imediatamente após a primeira pintura5 – Contém apenas conteúdo estático essencial18
SSRH3 – HTML é gerado em cada solicitação e não armazenado em cache4 – A primeira renderização será mais rápida porque o servidor renderizou a primeira passagem2 – Mais lento porque JS precisa hidratar DOM após a primeira análise + pintura de HTML1 – Dependências renderizadas de HTML + JS precisam ser baixadas10
PRS5 – HTML é armazenado em cache em um CDN5 – Sem carga útil JS ou operações assíncronas5 – A página é interativa imediatamente após a primeira pintura5 – Contém apenas conteúdo estático essencial20
PRH5 – HTML é armazenado em cache em um CDN4 – A primeira renderização será mais rápida porque o servidor renderizou a primeira passagem2 – Mais lento porque JS precisa hidratar DOM após a primeira análise + pintura de HTML1 – Dependências renderizadas de HTML + JS precisam ser baixadas12

Principais vantagens

A pré-renderização para conteúdo estático (PRS) leva a sites de melhor desempenho, enquanto a renderização do lado do servidor com hidratação (SSRH) ou renderização do lado do cliente (CSR) pode levar a resultados abaixo do esperado.

Também é possível adotar várias abordagens para diferentes partes do site. Por exemplo, essas métricas de desempenho podem ser críticas para páginas da web voltadas para o público, para que possam ser indexadas com mais eficiência, embora possam ter menos importância depois que um usuário faz login e vê os dados da conta privada.

Cada caminho de renderização representa compensações em onde e como você deseja processar seus dados. O importante é que uma equipe de engenharia seja capaz de ver e discutir claramente essas compensações e escolher uma arquitetura que maximize a felicidade de seus usuários.

Leituras adicionais e considerações

Alguns outros fatores que você precisa considerar ao construir sites com muito conteúdo incluem a necessidade de um bom sistema de gerenciamento de conteúdo (CMS) para seus autores e a capacidade de gerar / modificar facilmente visualizações de mídia social e otimizar imagens para tamanhos variados de tela.

Confira mais artigos em nosso site!