JavaScript e SEO: desenvolvendo páginas indexáveis

Luiz Henrique dos Anjos
Contabilizei
Published in
8 min readJul 9, 2019

--

No conforto de um escritório, um desenvolvedor front-end aproveita todos os recursos do seu framework favorito (vamos considerar que seja o Vue) para criar mais uma aplicação web, dentre várias que já desenvolveu em sua carreira. A aplicação é um MVP de um portal de notícias, com poucas funcionalidades. Perto do lançamento, o especialista em SEO da empresa faz uma revisão e avisa que provavelmente nenhuma matéria aparecerá como resultado de uma pesquisa do Google. O desenvolvedor começa a investigar a causa do problema e descobre que, no ambiente de produção, é necessário entregar páginas com o conteúdo montado. Até então, ele tinha desenvolvido uma single-page application (SPA), que funciona totalmente client-side. Vamos ver o que isso quer dizer.

Client-side rendering: benefícios e limitações

Os frameworks e bibliotecas para front-end se tornaram populares desde o AngularJS. Isso possibilitou o desenvolvimento de aplicações web com interações mais ricas, porque não era mais necessário aguardar a resposta de uma requisição a cada troca de página. Isso deu aos sistemas características mais próximas às de programas instalados no computador em comparação ao comportamento de sites.

Como isso se tornou possível?

Falando agora sobre os frameworks mais modernos, Angular, Vue e React servem principalmente — mas não apenas — para a criação de SPAs. Esse tipo de aplicação favorece uma boa experiência do usuário e também torna a operação mais simples. É necessário apenas um servidor de arquivos estáticos, que normalmente são seguros, têm baixo custo, alta disponibilidade e alta escalabilidade. A maior preocupação é com o tempo de carregamento inicial. A partir disso, o tráfego de dados é apenas para enviar e receber informações, dispensando o uso da rede para a estrutura da aplicação.

É possível resumir o funcionamento das SPAs da seguinte forma:

  1. o navegador recebe um HTML vazio, com um JavaScript que contém o código da aplicação
  2. o JavaScript monta a página inicial da aplicação
  3. a partir daí, cada navegação dispensa uma requisição ao servidor, pois cada nova tela é construída pelo JavaScript, que apenas troca o conteúdo da página, sem mudar o usuário de página

Isso é bom para a experiência do usuário, mas para indexação em mecanismos de busca, mais especificamente o Google, essa estratégia não é muito amigável. Vamos ver o porquê.

Como funciona o Googlebot

O Googlebot é o software do Google responsável por descobrir e indexar conteúdo na web. Como existem muitas páginas para indexar, o Googlebot tem algumas limitações para economizar recursos e conseguir indexar a grande quantidade de páginas que precisa. Uma dessas limitações afeta justamente o JavaScript. O crawler faz a requisição da página ao servidor, lê e indexa o conteúdo do HTML. Como a execução do JavaScript para muitas páginas é uma tarefa custosa, o JavaScript da página tem sua execução agendada. Enquanto a indexação do conteúdo recebido no HTML é instantânea, qualquer mudança que o JavaScript faz na página só é percebida pelo robô do Google quando ocorre a execução, o que pode levar até uma semana. Além disso, não existe nem mesmo uma garantia de que todo o JavaScript da página será executado. Para cada página, o bot oferece um orçamento de execução, que é consumido a cada linha de código executada. Quando esse orçamento termina, a execução é interrompida e o bot indexa o resultado, que pode ser uma página incompleta.

Por conta dessas restrições, as SPAs normalmente não têm um bom desempenho nas buscas, porque o conteúdo demora de ser montado no Google e existe uma possibilidade de o conteúdo ser apenas parcialmente indexado.

Para ter um site ou aplicação web fácil de ser indexado, é possível usar outras estratégias. A mais intuitiva é montar a página no servidor a cada requisição e entregar o HTML pronto. Também é possível mesclar essa estratégia com o client-side rendering (CSR) para extrair os melhores benefícios para cada caso. A seguir, vemos essas estratégias, como funcionam e para quais casos são mais recomendadas.

Server-side rendering: o melhor amigo do SEO

Server-side rendering (SSR) é, basicamente, gerar um HTML no servidor toda vez que um cliente solicita uma página. Quando as páginas possuem conteúdos dinâmicos — como portais de notícias, por exemplo — sempre que um navegador tenta acessar a página, o servidor deve montar o HTML com o conteúdo que é lido do banco de dados. Se as páginas seguirem as melhores práticas de SEO, esse mecanismo de entrega não será um empecilho para que o Googlebot consiga indexar a página rapidamente.

Ao longo da história da web, várias linguagens de programação e ferramentas foram criadas para tornar mais simples a geração de HTML no lado do servidor. Mesmo com todo o avanço, sempre era necessário utilizar uma linguagem server-side (PHP, Java, entre outras) e outra para o código client-side (JavaScript). Os avanços do Node.js tornaram possível vencer essa barreira, criando o conceito de JavaScript isomórfico. Com essa técnica, é possível desenvolver a aplicação de forma que a estratégia de entrega não interfira no desenvolvimento. Com alguns cuidados, o desenvolvedor pode desenvolver a aplicação como desenvolveria uma SPA e uma ferramenta de SSR executa em um servidor Node e gera o HTML quando um navegador requisitar uma página. Nuxt.js para Vue.js, Next ou Gatsby para React e Universal para Angular são exemplos de ferramentas que permitem renderizar aplicações JavaScript no servidor.

Em comparação com o client-side rendering, a geração do HTML no servidor permite que todo o conteúdo da página seja indexado, mas cria uma demanda maior para escalabilidade e custos. Otimizações no código e no banco de dados, além do uso de cache podem mitigar a demanda, mas a estratégia client-side continua sendo melhor nesses quesitos.

Claramente o Googlebot e outros crawlers podem ser considerados usuários com necessidades diferentes dos usuários humanos. Seria interessante detectar no servidor que tipo de usuário está requisitando uma página e então escolher a estratégia que melhor se adequa. Veremos a seguir como é possível.

Dynamic rendering: o melhor de dois mundos?

O dynamic rendering (DR) é uma técnica simples, que resolve um problema grande. O cenário é: você tem uma aplicação web feita com JavaScript, client-side, mas precisa de indexação. O Googlebot não indexa muito bem conteúdos client-side. Como resolver? Ao invés de o servidor simplesmente entregar o conteúdo estático, você adiciona uma verificação do user-agent. Essa propriedade da requisição informa ao servidor quem está pedindo a página. Se o user-agent for de um crawler, você desvia a requisição para um servidor de aplicação, que vai montar o HTML e entregar o conteúdo pronto para o bot. Isso resolve o problema, sem criar uma preocupação grande com custos. Esse servidor de aplicação não tem requisito de escalabilidade, porque só será acionado quando o crawler passar. É uma solução tão boa, que o próprio Google tem uma ferramenta para fazer o papel do servidor de aplicação, o Rendertron.

Então temos a solução que parece ótima, sem pontos negativos. Até aqui, vimos problemas de custos, escalabilidade e capacidade de indexação, mas o dynamic rendering parece ser a solução. O artigo poderia terminar aqui, se isso solucionasse tudo. Mas não termina.

O dynamic-rendering não é perfeito. A técnica de usar client-side rendering como padrão e server-side rendering como exceção resolve os problemas de custo e indexação, mas não necessariamente oferece a melhor experiência para o usuário. É verdade que neste mesmo artigo eu afirmei que client-side rendering oferece uma boa experiência, porque as trocas de páginas e interações são mais rápidas, mas eu não falei sobre o carregamento inicial.

Considere que você tem uma página que mostra uma matéria sobre um assunto qualquer. Essa página também tem uma seção de comentários e uma barra lateral com links para matérias relacionadas. Usando CSR, quando o usuário acessa a página, o navegador primeiro recebe o código, que é praticamente apenas JavaScript. Depois disso, esse código é analisado, executado e, por último, a página é renderizada. Mas o usuário ainda não está vendo o conteúdo da matéria, nem os comentários e nem as matérias relacionadas. Depois de todo esse processo, o navegador faz as solicitações de conteúdo a um servidor de aplicação, aguarda o processamento de cada requisição, analisa a resposta e adiciona os conteúdos à página. Com otimizações, esse processo pode até não ficar lento, mas certamente não vai ser tão rápido quanto seria com SSR.

Com SSR, se o servidor que renderiza o HTML puder se comunicar em alta velocidade com o servidor do conteúdo — ou pelo menos mais rápido do que o navegador do usuário se comunica — , você elimina a espera causada pela latência da rede e consegue entregar o conteúdo mais rápido. O problema, nesse caso, é que o servidor precisará acessar três conteúdos no banco de dados antes de entregar a página pronta para o navegador (matéria, comentários e matérias relacionadas). Se você resolver otimizar a lógica no servidor, pode até fazer essas buscas simultaneamente ao invés de fazer sequencialmente. Mesmo assim, o tempo de resposta sempre será impactado pela busca mais demorada das três.

O que é Hybrid rendering e como isso poderia resolver esse problema

Hybrid rendering (HR) é uma técnica que utiliza o JavaScript isomórfico para renderizar partes da página no servidor e partes no navegador. No exemplo da página que exibe uma matéria, o ideal para a experiência do usuário é que ele tenha o conteúdo principal na tela o mais rápido possível. Se a página for exibida rapidamente, com esse conteúdo, mas as matérias relacionadas e os comentários não aparecerem, tudo bem. O usuário provavelmente só prestará atenção nesses outros elementos em um segundo momento. Para entregar a matéria o mais rápido possível, o servidor busca apenas o conteúdo da matéria no banco de dados e monta o HTML. Dessa forma, assim que o navegador receber a página, o texto é exibido imediatamente. Depois, no lado do cliente, o navegador começa a solicitar as matérias relacionadas e os comentários, inclusive podendo postergar o carregamento de acordo com a rolagem da tela.

Isso aumenta o custo de operação em relação ao client-side, reduz a capacidade de indexação apenas ao conteúdo principal da matéria — o que pode não ser um problema para SEO — , mas entrega o conteúdo o mais rápido possível. Isso é um dos critérios utilizados pelo algoritmo do Google para definir o ranking de cada página de uma pesquisa e pode fazer sua página aparecer entre os primeiros resultados.

Tá, mas qual eu devo usar?

Cada uma dessas quatro técnicas tem cenários em que se adequa melhor. Em resumo, client-side rendering é bom para aplicações web que precisam de boa interatividade e não têm conteúdo que precisa ser indexado. A página que mostra a fatura do seu cartão de crédito é um bom exemplo disso. Server-side rendering, por outro lado, é a forma mais simples de ter conteúdo indexado, com o ônus de ser mais custoso para manter em operação. Dynamic rendering é uma adaptação que permite que a aplicação se comporte como client-side para humanos e como server-side para crawlers. É uma boa forma de ter conteúdo indexável, sem um custo tão alto de operação. Hybrid rendering é uma forma mais elaborada de entregar a melhor experiência de carregamento de conteúdo principal, desde que o restante do conteúdo não precise ser indexado.

O objetivo deste artigo não é guiar a escolha de uma dessas quatro técnicas para entrega de páginas, até porque não existem apenas essas quatro. Para o site da Contabilizei, por exemplo, utilizamos geração de HTML em tempo de build, que não se encaixa em nenhuma das categorias apresentadas. O objetivo real é mostrar que, embora o ambiente de desenvolvimento seja o ambiente com o qual o desenvolvedor tem mais contato, o ambiente de produção é o mais importante. É onde o seu código será executado. A escolha correta das características desse ambiente pode determinar se um projeto terá sucesso ou não. Tenha em mente seus requisitos funcionais e não-funcionais e faça uma escolha consciente.

--

--