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.
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.
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.
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.
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:
- 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.
- Na segunda fase, ele foi publicado para mais páginas, totalizando alguns milhares de usuários por dia.
- 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% |
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%.
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".
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).
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.
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.