Como a QuintoAndar aumentou as taxas de conversão e as páginas por sessão ao melhorar o desempenho

Um projeto focado na otimização das Core Web Vitals e a migração para o Next.js resultou em um aumento de 5% nas taxas de conversão e de 87% nas páginas por sessão.

Daniela Sayuri Yassuda
Daniela Sayuri Yassuda

A QuintoAndar é uma empresa brasileira de proptech que oferece soluções digitais completas para o setor imobiliário. Neste ano, realizamos um projeto focado em melhorar o desempenho de um hub de conteúdo no nosso app e tivemos resultados encorajadores no aumento do tráfego de usuários e das métricas de conversão.

46%

de redução na taxa de rejeição

87%

de aumento nas páginas por sessão

5%

de melhoria na conversão durante a fase de validação

Desafios

Nosso app tem um hub de conteúdo de condomínios com mais de 40 mil páginas, onde os usuários podem conseguir informações sobre suas propriedades, conferir fotos das áreas comuns, ler sobre o bairro e encontrar anúncios disponíveis para aluguel ou venda. Estas páginas são muito importantes para QuintoAndar:

  • Elas são uma fonte importante de tráfego orgânico, com um número crescente de usuários provenientes de resultados de mecanismos de pesquisa.
  • Eles têm altas taxas de conversão no médio e longo prazo em comparação com outras páginas.

No entanto, houve desafios em relação ao desempenho e à experiência do usuário nessas páginas:

  • O desempenho avaliado pelas Core Web Vitals não foi otimizado, e houve problemas conhecidos relacionados a lentidão no carregamento de páginas, lentidão na resposta à entrada do usuário e instabilidade no layout.
  • As taxas de rejeição foram altas, mesmo se esperávamos que elas fossem mais altas do que em outras partes do aplicativo.
  • A atualização da experiência na página na Pesquisa Google, que na época ainda não foi lançada, incluiria as Core Web Vitals no algoritmo de classificação, o que significa que o desempenho da página poderia afetar como os resultados da pesquisa seriam exibidos.

Ao mesmo tempo, identificamos algumas oportunidades de experiência do desenvolvedor que poderiam gerar ganhos em outros projetos na empresa:

  • Nossa lógica de renderização do lado do servidor, que renderiza todas as páginas de alto tráfego, incluindo páginas de condomínios, foi criada internamente e se tornou muito complexa para manter e integrar novas contratações.
  • Os recursos essenciais para alcançar um bom desempenho do app, como a divisão de código, também exigiam uma configuração personalizada e o trabalho manual dos desenvolvedores.
  • A QuintoAndar tem mais de 30 aplicativos da Web do React. Entregar atualizações e manter esses aplicativos de acordo com as práticas recomendadas é uma tarefa árdua.

Abordagem

Começamos um projeto de otimização de performance do hub de conteúdo de condomínios para melhorar a experiência do usuário, já que essas melhorias poderiam levar a ganhos de conversão, melhor SEO e melhor usabilidade. Essa iniciativa também foi uma oportunidade adequada para melhorar a experiência dos desenvolvedores.

Como migrar para o Next.js

A nova versão da página do condomínio foi implementada com Next.js. Por ser amplamente independente de outras partes do app, o hub de conteúdo de condomínios parecia ser um bom candidato para testar uma nova estrutura. Poderíamos entender a magnitude dos esforços de migração e avaliar como os recursos podem ajudar sem afetar os outros aplicativos React no QuintoAndar.

Um requisito importante era garantir que as páginas pudessem ser rastreadas pelos mecanismos de pesquisa. O Next.js atende a esse requisito oferecendo suporte à renderização imediata do lado do servidor e elimina a necessidade de uma configuração personalizada. Com a documentação, é muito mais fácil compartilhar conhecimento sobre como realizar tarefas como a busca de dados no servidor e a integração de novos desenvolvedores. A renderização do lado do servidor também é conhecida por melhorar as métricas de desempenho, como a Primeira exibição de conteúdo (FCP, na sigla em inglês).

O framework fornece outros recursos com foco no desempenho, como divisão de código automática e pré-busca. A estrutura atual já fornecia esses recursos, mas o trabalho extra exigido dos desenvolvedores impediu a adoção. Por exemplo, a divisão de código no nível da página ou do componente precisava ser feita manualmente.

Otimizar recursos JavaScript

A primeira etapa foi remover o código não utilizado. Analisamos os relatórios do Webpack Bundle Analyzer, que mostram o conteúdo de cada pacote JS, e analisamos todos os scripts de terceiros. Como resultado, pudemos limpar algumas bibliotecas de acompanhamento que não eram usadas nessa página específica.

Nossa equipe foi além e avaliou o custo de desempenho dos recursos existentes. Por exemplo, o botão "curtir" exigiu bastante JavaScript para funcionar. No entanto, na página do condomínio, menos de 0,5% dos usuários interagiram com o botão, que está disponível e usado com mais frequência em outras partes do app. Após uma discussão envolvendo engenharia e produto, decidimos remover esse recurso.

Uma animação mostrando o recurso do botão "Gostei". Há um card sobre um apartamento disponível para aluguel. No canto inferior direito do card, há um botão cinza em forma de coração que fica azul quando clicado.

Outras otimizações de JS já estavam em vigor, como a compressão estática com o Brotli, que era feita no tempo de compilação usando BrotliWebpackPlugin e também era aplicada a outros tipos de recursos estáticos. No início, estávamos contando com a compactação fornecida pelo CDN, e o Brotli reduziu o tamanho do JS em 18% em comparação com o gzip. No entanto, mudamos para a compressão Brotli durante a compilação e conseguimos uma redução de 24%.

Como otimizar recursos de imagem

Na versão para dispositivos móveis, há uma imagem principal ocupando a maior parte da área acima da dobra. Ela também é a Maior exibição de conteúdo (LCP, na sigla em inglês) da página.

Página do condomínio do Edifício Copan (São Paulo, Brasil). Uma foto tirada do nível do solo mostra as curvas da estrutura do prédio.
A imagem principal de uma página de condomínio.

Antes, todas as imagens já tinham os atributos srcset e sizes para veicular imagens responsivas. Também usamos o Thumbor para redimensionar imagens sob demanda e configuramos nossa CDN para armazená-las em cache de maneira eficiente.

Os dispositivos móveis modernos têm telas com densidade de pixels muito alta, o que significa que o navegador renderizaria versões de 3x ou 4x da imagem, se disponíveis. Com o aumento da resolução, fica mais difícil para o olho humano perceber as diferenças, mas o tamanho dos arquivos aumenta de qualquer maneira. Limitar a resolução máxima da imagem melhorou o tamanho da imagem sem comprometer a experiência do usuário. Limitamos a imagem hero para servir no máximo sua versão 2x, que é aproximadamente 35% menor do que a versão 3x e 50% menor que a versão 4x.

Para finalizar, usamos uma estratégia de pré-carregamento para fazer o download e mostrá-lo o mais rápido possível, na medida do possível para melhorar a métrica de LCP.

<link rel="preload" href="/img/450x450/892847321-143.0038687080606IMG20180420WA0037.jpg" as="image">

O componente de imagem integrado do Next.js inclui muitas dessas otimizações, como redimensionamento responsivo e carregamento priorizado. Durante este projeto, não migramos as imagens existentes para usar esse componente, mas estamos planejando adotá-lo em novos recursos.

Como reduzir a mudança de layout

A página do condomínio teve alguns problemas com a Mudança de layout cumulativa (CLS, na sigla em inglês). Os elementos responsáveis pelas mudanças de layout foram renderizados apenas no cliente, por exemplo, hidratar a marcação do lado do servidor com componentes renderizados pelo cliente ou imagens sem os atributos width e height definidos.

Para resolver esses problemas, definimos dimensões exatas para esses elementos quando possível ou valores estimados com min-height. Há mais opções, como usar a propriedade CSS aspect-ratio. Também criamos marcadores de posição para evitar que componentes renderizados dinamicamente causem mudanças de layout.

Imagem que mostra uma área urbana no Google Maps com um marcador vermelho no centro.
Definir dimensões para elementos como a imagem do mapa reduziu a CLS.

Como implementar mudanças progressivamente

Nossa equipe queria validar que a versão otimizada da página do hub do condomínio para garantir que a experiência do usuário seria melhor. Para isso, adotamos uma estratégia de lançamento progressivo:

  1. Na primeira fase, a nova versão foi publicada para alguns URLs escolhidos a dedo, então apenas algumas centenas de usuários por dia teriam acesso a eles.
  2. Na segunda fase, ele foi publicado para mais páginas, totalizando alguns milhares de usuários por dia.
  3. Na terceira e última fase, ele foi publicado para todas as páginas, e o lançamento foi concluído para todos os usuários.

Durante esse período, a equipe de engenharia mediu continuamente o desempenho da página na produção e continuou trabalhando em melhorias. Além disso, a equipe comparou as métricas de negócios entre a versão nova e a anterior. Os resultados nesse período de validação foram promissores.

Resultados

A equipe usou SpeedCurve para executar continuamente testes de laboratório na página do condomínio. Estes são os resultados da versão para dispositivos móveis:

Métrica do laboratório Antes Depois Diferença
Maior exibição de conteúdo (LCP) 2,41 segundos 1,48 segundo 39%
Tempo para interação da página (TTI, na sigla em inglês) 12,16 segundos 7,48 segundos 39%
Tempo total de bloqueio (TBT) 1.124 milissegundos 1.056 milissegundos 4%
Cumulative Layout Shift (CLS) 0,0402 0,0093 77%
Resultados de métricas de laboratório coletados com o SpeedCurve.

Também queríamos verificar o impacto em nossos usuários reais. Usando dados de campo coletados com o Monitoramento de sites da Instana, analisamos o período de um mês antes e depois do lançamento. Comparando o 75o percentil dos usuários de dispositivos móveis, descobrimos que a LCP diminuiu 26% e a FID diminuiu 72%.

Um gráfico de linhas com valores de LCP comparando as versões nova e anterior no mês atual e no anterior. A curva da nova versão flutua entre 2 e 4 segundos, permanecendo abaixo da curva da versão anterior na maior parte do tempo.
Um gráfico de linhas com valores de FID comparando as versões nova e anterior no mês atual e no anterior. A curva da nova versão permanece abaixo de 100 ms na maior parte do tempo, enquanto na curva da versão anterior há alguns picos cruzando 250 ms.
Resultados de métricas de campo coletados com a Instana.

O PageSpeed Insights disponibiliza um relatório de dados de campo dos últimos 28 dias. Só a página do condomínio mais acessada tinha dados suficientes para gerar um relatório para usuários de dispositivos móveis. Desde novembro de 2021, todas as Core Web Vitals estão na faixa "boa".

Uma captura de tela do relatório do PageSpeed Insights com foco na seção &quot;Dados de campo&quot;. Todas as métricas das Core Web Vitals (FCP, FID, LCP, CLS) estão no bom nível.
O PageSpeed Insights mostra que os usuários de dispositivos móveis têm uma boa experiência na página do condomínio mais acessada.

Durante o lançamento progressivo, notamos uma queda nas taxas de rejeição. Quando concluímos o lançamento de todas as páginas, o Google Analytics mostrou uma redução de 46% na taxa de rejeição, um aumento de 87% nas páginas por sessão e um aumento de 49% na duração média da sessão. A redução da taxa de rejeição foi ainda maior para pesquisas pagas, alcançando uma queda de 59%, um sinal positivo quando se trata dos investimentos em anúncios de pagamento por clique (PPC).

Uma captura de tela de um gráfico do Google Analytics. Ele compara as taxas de rejeição entre dois períodos diferentes em março de 2021. A partir de 17 de março, há uma pequena queda na taxa de rejeição. A queda é acentuada em 24 de março.
O Google Analytics mostra que a taxa de rejeição está diminuindo à medida que lançamos a nova versão em mais páginas.

Quanto ao impacto nas métricas de negócios, analisamos as taxas de conversão para transações como agendamento de uma turnê e inscrições para alugar ou comprar um imóvel. Embora as melhorias ainda estivessem sendo lançadas, nossa equipe comparou a conversão entre a versão anterior e a nova. Na mesma semana, o grupo de páginas com a nova versão apresentou um aumento de 5% nas conversões, enquanto as outras páginas tiveram uma leve queda na mesma métrica.

Dois gráficos de linhas lado a lado, cada um comparando a conversão entre a semana atual e a anterior. O que está à esquerda é para a versão anterior da página, mostrando que a curva de conversão da semana atual está um pouco abaixo da curva anterior. O certo é para a versão nova, e a curva de conversão da semana atual está um pouco acima da curva anterior.
Na mesma semana, a conversão da nova versão aumentou, e a versão anterior teve uma pequena redução.

Conclusão

Esse projeto é a primeira parte de um esforço de migração de longo prazo do React para Next.js, sem framework. As equipes que trabalharam na página do condomínio desde então deram feedback positivo sobre a experiência aprimorada do desenvolvedor. Outras equipes que precisavam inicializar novos aplicativos da web já fizeram isso com o Next.js. Acreditamos que o Next.js vai simplificar os esforços de manutenção e estabelecer um terreno comum entre diferentes apps.

No geral, o hub de conteúdo de condomínios tem crescido continuamente em termos de número absoluto de usuários e transações. Na análise de longo prazo, há muitos fatores que contribuem para isso, como a expansão das operações de QuintoAndar e das iniciativas de SEO, como a melhoria da indexação de páginas. Durante esse projeto, vimos que o desempenho da página também é um desses fatores com grande potencial para impacto positivo nas conversões.

Um agradecimento especial a Pedro Carmo, gerente de produtos da equipe de SEO, por analisar os dados do usuário e criar todas as análises de conversão mostradas neste estudo de caso.