Rafhael Marsigli Logo
Menu
Fale Comigo

Servindo Sites Pesados com Pagespeed Altíssimo Usando a Mesma Metodologia

Vários

Desenvolvimento Frontend, Web Design

Desenvolvedor Full Stack com foco em performance frontend

Embora eu seja um desenvolvedor backend "de fábrica", ainda faço muitos trabalhos de web design de sites e landing pages, principalmente depois que comecei a trabalhar com Rush CMS. A ideia do Rush CMS é a agência ter um CMS headless totalmente dinâmico, enquanto tem a liberdade de servir um frontend da forma que ela quiser.

No meu caso, essa forma é otimização:

  1. O cliente faz o briefing de como quer o layout
  2. Eu já preparo o mockup pensando em velocidade
  3. O cliente aprova, ou faz as alterações que ele quer. Nesse caso, o cliente é rei, se ele quer algo pesado na frontpage, ele vai ter. Eu apenas aviso na questão de performance, presto uma consultoria, e a decisão dele é a final
  4. Depois disso, eu faço todas as otimizações possíveis para o site performar

A melhor abordagem que encontrei - de forma disparada - começa com Astro e Bun como base.

Por que Astro?

Eu já testei várias abordagens: React puro, Svelte, Tanstack, Next.js, React Router, Gatsby, Hugo... E de todos, Astro foi o único que foi feito primariamente para essa abordagem: sites e landing pages. Ele não tenta abraçar o mundo, nem atender uma gama de necessidades. Seu objetivo principal é fazer sites e landing pages de forma otimizada, e só. O bundle tem um tamanho ridiculamente pequeno, e se você precisar de abordagens mais avançadas, pode usar o framework que preferir dentro de uma island.

Caso queira saber mais, explico detalhadamente nesse artigo do meu blog, todos meus posts sobre Astro podem ser lidos aqui.

Por que Bun?

Aqui é mais simples: velocidade. Em produção, nada muda, continuamos usando o padrão da indústria. Localmente rodo bun install até 10x mais rápido, bun dev e bun run build mais (mas não tão) rápidos, e com menos overhead de inicialização. É uma diferença que faz sentido pra mim. Confesso que fiquei até mal acostumado! Sinto falta quando estou trabalhando em um projeto que não tenha isso.

Não é uma regra, é uma facilidade que eu não vejo o motivo de abandonar.

E a Metodologia?

Eu já expliquei o setup, agora vou explicar a mentalidade. Enquanto vou detalhando alguns sites que tenho como exemplo, vou trazer uma abordagem que fez a diferença em cada um.

CTB Brasil

A CTB Brasil opera em um ramo que sua front-page precisa de muitas fotos, seus clientes precisam saber tudo que ela opera em uma página só: que tipos de serviços faz, para quem presta serviços, que equipamentos tem para locação e etc.

O ramo de construção civil não tem um histórico de aderência em massa de novas tecnologias, correr o risco de perder clientes por que o site é "moderno demais" é um payoff que não compensa, nem um pouco. A solução foi trazer modernidade com muita sobriedade.

No momento que escrevo esse case, a homepage do site conta com mais de 50 imagens e um Pagespeed 97.

O que fez a diferença: com exceção do que é mostrado acima da dobra, todas as imagens possuem: height/width explícitos que irão dizer ao navegador os tamanhos exatos dessa imagem (isso importa mais do que parece); loading="lazy" adia o carregamento da imagem (mandatório nesse caso), elas só carregam quando o usuário rola até ela; decoding="async" vai permitir o navegador processar em segundo plano, impedindo que ela trave o restante do código html de ser processado.

50+ Imagens na homepage e Pagespeed 97

Como eu falei no começo, o conteúdo acima da dobra - o que o usuário vê primeiro, assim que a página abre - é o oposto do que fiz no resto do site. Nada de loading="lazy", essa imagem na verdade precisa de fetchpriority="high" (avisa o navegador que aquela é a imagem mais importante da página, e carrega com prioridade). E quando o projeto deixa, um <link rel="preload"> no <head> pra começar o download antes mesmo do parser chegar na tag. Não usar essas boas práticas vai arrancar pelo menos uns 10 pontos da sua nota!

Mega Model Sul

O Mega Model Sul não usa Rush CMS, mas se conecta diretamente com uma plataforma interna, que fornece as informações do site e captam leads. Esse projeto trouxe um desafio diferente, o hero é um vídeo, mas que eu não posso otimizar como eu quero. O motivo? quando celulares como o iPhone estão com baixa bateria, o Safari não executa o autoplay do vídeo no background. Para os proprietários, esse autoplay precisa acontecer, não importa como.

A solução foi sacrificar alguns pontos de desempenho e entregar o máximo possível, lembre-se: atender o cliente é mandatório, e só depois disso, devo chegar no melhor resultado possível. Ao invés de usar o vídeo padrão e otimizado, eu converti em webp animado, que na prática é um gif, mas tecnicamente é uma compressão e empacotamento de vários frames em um único arquivo, de forma mais moderna. Usei ffmpeg com libwebp para pegar os frames e gerar os arquivos automaticamente.

Essa abordagem engana o navegador, fazendo com que o vídeo seja exibido, não importando se o mundo está acabando ou o navegador não queira. Testei várias opções diferentes para encontrar o arquivo mais leve possível e com o framerate mais adequado.

O que fez diferença: O projeto é um Astro SSR, a página é renderizada no servidor, mas as APIs que alimentam a interatividade - listagem de estados, cidades, busca de modelos - retornam com Cache-Control agressivo (max-age=86400 para listas estáveis, stale-while-revalidate=3600 para a busca), então o navegador e a CDN absorvem o grosso da carga. Para as partes interativas em si - busca, filtros, galeria - usei Preact com compat layer, que entrega a mesma API do React por cerca de 1/10 do tamanho do bundle. Cada componente interativo vira uma island hidratada sob demanda, então o usuário paga o custo do JS só do que ele realmente usa. O webp animado rouba a cena, mas é o conjunto SSR + cache nas APIs + islands com Preact que sustenta o Pagespeed mesmo com o vídeo "trapaceado" no hero.

Padaria Esquina do Pão

A Padaria Esquina do Pão é uma padaria de referência em Caraguatatuba - SP que possui um site com cardápio online. O desafio aqui foi diferente dos outros: o cardápio precisa estar sempre atualizado. Produto que acabou tem que sumir, preço novo tem que aparecer, item sazonal entra e sai. O dono não pode esperar build, deploy e cache invalidation cada vez que mexe no cardápio.

Para sites estáticos isso normalmente é um problema: ou você "rebuilda" o site a cada mudança (lento), ou serve tudo dinâmico e perde performance. A solução foi um meio termo: Astro em modo SSR com revalidação por webhook.

O que fez a diferença: o site roda em SSR via @astrojs/node, e as respostas do Rush CMS ficam em um cache interno indexado por chave (cada listagem, cada entry, cada menu). Quando o cliente edita algo no CMS, um webhook autenticado bate no endpoint /api/revalidate com a chave do que mudou - se vier uma chave específica, invalida só aquela; se vier vazio, invalida tudo.

O usuário recebe a página em poucos milissegundos com cache quente, o dono vê a alteração no ar rapidamente, e ninguém precisa rebuildar nada. Configurei também o envField com schema validado no astro.config.mjs, então variáveis de ambiente faltando ou mal formatadas quebram no build, não em produção, uma rede de segurança que evita aquele "funciona no local mas não na produção".

Pórtico Reformas

A Pórtico Reformas trabalha com reformas residenciais de luxo e alto padrão em Porto Alegre, ele tem cara de site institucional mas entrega um sistema próprio de landing pages para atender os principais nichos.

Páginas de especialidades como Condomínio Premium e Reformas em Apartamento entregam aquilo que é necessário para o cliente, SEO e agentes. Todos com thumbnail geradas automaticamente e componentes em formato de blocos .astro, possibilitando gerar dezenas de páginas específicas para um tipo de serviço, área de atuação, localização ou nicho com a mesma qualidade técnica.

Pórtico Reformas gerando meta image automaticamente

O projeto envolve vários eixos, sendo como principal: site SSG com conteúdo dinâmico fornecido pelo Rush CMS (com formulário de contato integrado ao sistema) e geração dinâmica de Open Graph images para cada especialidade do portfólio.

O que fez a diferença: usei satori com @resvg/resvg-js para gerar OG images em build time a partir de um template JSX, com o hero de cada especialidade como fundo, badge, título e CTA renderizados em cima. O resultado é um .jpg de 1200x630 por especialidade, servido com Cache-Control: public, max-age=31536000, immutable. Quando alguém compartilha um link no WhatsApp ou Facebook, a prévia é gerada uma vez e cacheada para sempre, sem que ninguém precise abrir o Photoshop ou qualquer programa de edição de imagem.

No frontend, a galeria usa photoswipe carregado como island: o js da galeria só baixa quando o usuário clica para abrir uma foto. O resto da página continua sendo HTML estático puro, e o Pagespeed agradece.

Aprendizados

A coisa mais importante que aprendi - e continuo aprendendo - fazendo sites para o Rush CMS e para a Mega Model é que performance não é uma meta, é uma consequência. Não dá pra abrir um projeto novo e dizer "vou tirar Pagespeed 100", você abre, entende o que o cliente precisa, e a partir daí escolhe que ferramenta usar pra cada problema.

E é por isso que stack diferente nunca é problema. CTB, Mega Model, Esquina do Pão e Pórtico têm necessidades completamente diferentes e cada um resolveu seu desafio do seu jeito, mas a mentalidade é sempre a mesma: só carrega o que precisa, quando precisa, e do jeito mais leve possível. Astro me dá a flexibilidade pra fazer isso sem brigar com a ferramenta, e por isso ele vira meu ponto de partida em todo projeto novo de site ou landing page.