WordPress para Astro: Como Atingimos Lighthouse 100 (Sua Agência Também Consegue)
Sua agência prega performance, mas seu próprio site WordPress anda lentamente. O nosso também — 3.2 segundos até Interactive, Lighthouse preso em 58, uma pilha de plugins que tínhamos medo de atualizar. A cada demo de cliente significava abrir devtools no seu site estático super rápido, rezando para que não perguntassem para ver o nosso. Somos socialanimal.dev — construímos experiências sub-segundo em Next.js e Astro para marcas SaaS. Então reconstruímos nosso site em Astro, eliminamos completamente WordPress, e atingimos 100 perfeitos em todas as categorias do Lighthouse. Time to Interactive caiu para 0.4 segundos. Tamanho total do bundle: 47 KB. Sem plugins, sem queries de banco de dados, sem constrangimento.
Ento desmontamos tudo e reconstruímos com Astro. O resultado: 100 perfeitos em todas as quatro categorias do Lighthouse — Performance, Acessibilidade, Melhores Práticas e SEO. Não em uma única página. Em cada página. Esta é a história de como chegamos lá, o que quebrou pelo caminho, e o que faríamos diferente.
Sumário
- Por Que Deixamos WordPress
- Por Que Escolhemos Astro
- A Estratégia de Migração
- Decisões de Arquitetura Que Fizeram a Diferença
- Deep Dive em Otimizações de Performance
- O Scorecard Lighthouse 100
- Antes e Depois: Os Números
- O Que Erramos Pelo Caminho
- Lições Para Sua Própria Migração
- FAQ

Por Que Deixamos WordPress
Olha, WordPress alimenta algo como 43% da web. Não é uma plataforma ruim. Criamos vários sites WordPress para clientes e continuaremos fazendo assim quando for o encaixe certo. Mas para nosso próprio site de agência — um site de marketing praticamente estático com um blog — WordPress era exagerado da pior forma.
Aqui está como era nossa configuração WordPress:
- Theme: Custom theme construído em Sage (Roots.io)
- Plugins: 14 plugins ativos incluindo Yoast SEO, WP Rocket, Advanced Custom Fields Pro, Gravity Forms, e alguns outros
- Hosting: WP Engine Professional plan em $60/mês
- CDN: Cloudflare Pro em $20/mês
- Complexidade de build: Templating PHP, Webpack para assets, banco de dados MySQL
Mesmo com WP Rocket fazendo cache agressivo, nossos Core Web Vitals eram mediocres. O Largest Contentful Paint (LCP) era 2.4 segundos em mobile. Cumulative Layout Shift (CLS) era 0.12 — não terrível, mas não bom. E cada vez que atualizávamos um plugin, havia uma possibilidade não-zero de algo quebrar.
O real problema? Estávamos pagando $80/mês em hospedagem para um site que recebia talvez 3,000 visitas por mês. Não é muito tráfego, e é muito dinheiro para o que era essencialmente um site de brochura com um blog.
O Ponto de Quebra
O último golpe veio em janeiro de 2025. Uma atualização do WordPress core quebrou nossos blocos Gutenberg customizados. Corrigir exigiu atualizar ACF Pro, que exigiu atualizar a compatibilidade de versão PHP do nosso theme, que exigiu atualizar o ambiente de hospedagem. O que deveria ser uma atualização de rotina se tornou um dia inteiro de trabalho.
Olhei para nosso time e disse: "Dizemos aos clientes para ir headless. Por que não estamos comendo nosso próprio cachorro?"
Por Que Escolhemos Astro
Avaliamos quatro opções para a reconstrução:
| Framework | Vantagens | Desvantagens | Nosso Voto |
|---|---|---|---|
| Next.js | Conhecemos bem, ótimo ecossistema | Exagerado para um site de conteúdo, requer servidor ou edge runtime | Muito pesado |
| Astro | Focado em conteúdo, envia zero JS por padrão, arquitetura de ilhas | Ecossistema menor, mais novo | Encaixe perfeito |
| Eleventy | Simples, builds rápidos, maduro | Modelo de componentes limitado, DX menos moderno | Segunda opção próxima |
| Hugo | Builds incrivelmente rápidos, binário único | Templating Go é doloroso, flexibilidade limitada | Não para nós |
Construímos muitos projetos Next.js para clientes, e é nossa escolha padrão para qualquer coisa com funcionalidade dinâmica. Mas para um site de marketing pesado em conteúdo? Next.js envia um runtime JavaScript quer você precise ou não. Mesmo com export estático, você está enviando React para o navegador.
A filosofia do Astro ressoava conosco: envie HTML, adicione JavaScript apenas onde você precisar. Sua arquitetura de ilhas significa que você pode ter um componente React totalmente interativo sentado ao lado de HTML completamente estático, e as partes estáticas enviam zero JavaScript. Era exatamente o que precisávamos.
Também tínhamos feito mais trabalho de desenvolvimento Astro para clientes ao longo dos anos recentes, então o time estava confortável com o framework. Não era um exercício de aprendizado — era uma ferramenta que já confiávamos.
A Questão da Camada de Conteúdo
Uma decisão que tomamos no início: não íamos usar um CMS headless para nosso próprio site. Para projetos de cliente, frequentemente recomendamos configurações de CMS headless com Contentful, Sanity, ou Storyblok. Mas para nosso blog, onde cada autor é um desenvolvedor confortável com Markdown e Git? Content Collections em Astro com arquivos MDX commitados no repo era mais simples e rápido.
Sem chamadas de API no tempo de build. Sem rede de entrega de conteúdo para conteúdo. Sem serviço extra para gerenciar ou pagar. Apenas arquivos em uma pasta.
A Estratégia de Migração
Não fizemos uma migração big-bang. Aqui está nossa abordagem em fases:
Fase 1: Auditoria de Conteúdo (1 semana)
Exportamos todo o conteúdo WordPress usando wp-cli e convertemos posts para MDX usando um script customizado construído com turndown (conversor HTML-para-Markdown) mais alguma limpeza regex. Tínhamos 47 posts no blog na época. Cerca de 12 deles eram desatualizados ou com baixo desempenho, então redirecionamos para conteúdo relevante mais novo e não os migramos.
Fase 2: Design System em Astro (2 semanas)
Reconstruímos nossa biblioteca de componentes como componentes Astro. Buttons, cards, layouts de seção, navegação — todos como arquivos .astro. Nenhum framework necessário para nenhum deles. HTML puro e CSS com estilos scopados.
Fase 3: Page Build (2 semanas) Página inicial, pages de capabilities, sobre, contato, listagem de blog, posts de blog individuais, 404. Construímos todos como páginas Astro com nossa biblioteca de componentes.
Fase 4: Performance Tuning (1 semana) Aqui é onde o trabalho real do Lighthouse 100 aconteceu. Mais sobre isso abaixo.
Fase 5: Launch e Redirect (2 dias) Configuramos redirects 301 adequados para cada URL antiga, verificamos com Screaming Frog que nada estava quebrado, enviamos o novo sitemap para Google Search Console, e trocamos o DNS.
Tempo total: cerca de 6 semanas de trabalho part-time ao lado de projetos de clientes.

Decisões de Arquitetura Que Fizeram a Diferença
Zero JavaScript por Padrão
Nosso site inteiro envia aproximadamente 2KB de JavaScript total. Isso não é digitação errada. Dois kilobytes. E a maior parte disso é um pequeno script para toggle de navegação mobile e analytics.
Aqui está nossa nav mobile — sem framework, sem dependências:
---
// MobileNav.astro
---
<button id="menu-toggle" aria-expanded="false" aria-controls="mobile-menu">
<span class="sr-only">Toggle menu</span>
<svg><!-- hamburger icon --></svg>
</button>
<nav id="mobile-menu" hidden>
<slot />
</nav>
<script>
const toggle = document.getElementById('menu-toggle');
const menu = document.getElementById('mobile-menu');
toggle?.addEventListener('click', () => {
const expanded = toggle.getAttribute('aria-expanded') === 'true';
toggle.setAttribute('aria-expanded', String(!expanded));
menu?.toggleAttribute('hidden');
});
</script>
Esse <script> tag em um componente Astro é bundled e deduplicated automaticamente. É tiny, é vanilla JS, e funciona em todo lugar.
Estratégia CSS: Estilos Scopados + Uma Camada Global Mínima
Usamos CSS scopado built-in do Astro para estilos no nível de componentes e uma única stylesheet global (cerca de 8KB minificado) para tipografia, reset, custom properties, e utility classes. Sem Tailwind. Opinião controversa, eu sei.
Amamos Tailwind para aplicações maiores e projetos de clientes. Mas para um site desse tamanho, adicionava complexidade de build e tamanho de arquivo que não precisávamos. Nosso CSS escrito à mão é menor do que a saída do Tailwind teria sido, mesmo com purging.
/* Global custom properties */
:root {
--color-text: #1a1a2e;
--color-bg: #ffffff;
--color-accent: #e94560;
--color-accent-dark: #c81e45;
--font-body: 'Inter', system-ui, sans-serif;
--font-heading: 'Cal Sans', var(--font-body);
--max-width: 72rem;
--space-unit: 0.25rem;
}
Geração Estática com Smart Preloading
Cada página é gerada estaticamente no tempo de build. Usamos a integração prefetch built-in do Astro para preload de links em hover, tornando a navegação instantânea:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
export default defineConfig({
site: 'https://socialanimal.dev',
integrations: [mdx(), sitemap()],
prefetch: {
prefetchAll: false,
defaultStrategy: 'hover',
},
build: {
inlineStylesheets: 'auto',
},
});
Deep Dive em Otimizações de Performance
Chegar a Lighthouse 100 não é apenas sobre escolher o framework certo. Astro te dá uma vantagem inicial, mas os últimos 10-15 pontos requerem esforço deliberado. Aqui está o que fizemos.
Otimização de Imagens
O componente <Image /> built-in do Astro lida com imagens responsivas com conversão automática de formato (WebP/AVIF), lazy loading, e atributos width/height apropriados para prevenir CLS.
---
import { Image } from 'astro:assets';
import heroImage from '../assets/hero.jpg';
---
<Image
src={heroImage}
alt="Social Animal development team working on headless architecture"
widths={[400, 800, 1200]}
sizes="(max-width: 600px) 400px, (max-width: 900px) 800px, 1200px"
format="avif"
fallbackFormat="webp"
quality={80}
loading="eager"
/>
Para a imagem hero especificamente, usamos loading="eager" já que está acima do fold. Tudo mais recebe loading="lazy" por padrão.
Também passamos por cada imagem no site e perguntamos: "Isso precisa ser uma imagem?" Vários elementos decorativos se tornaram gradientes CSS ou SVGs. A background da nossa seção hero, por exemplo, é um gradiente CSS com uma textura noise sutil aplicada via um SVG inline tiny.
Estratégia de Carregamento de Fontes
Fontes são um killer do Lighthouse. Aqui está nossa abordagem:
Self-host tudo. Sem Google Fonts CDN. Baixamos Inter e Cal Sans e servimos do nosso próprio domínio. Isso elimina uma DNS lookup, conexão TCP, e TLS handshake com fonts.googleapis.com.
Subset agressivamente. Usamos
glyphhangerpara analisar qual caracteres realmente usamos, então subsetamos nossas fontes compyftsubset. Nosso Inter Regular WOFF2 foi de 96KB para 18KB.Use
font-display: swapcom um fallback de fonte system cuidadosamente escolhido que combina com métricas de perto, minimizando layout shift durante o swap.Preload dos arquivos de fonte críticos:
<link rel="preload" href="/fonts/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/cal-sans-latin-600.woff2" as="font" type="font/woff2" crossorigin />
Hosting: Cloudflare Pages
Nos mudamos de WP Engine ($60/mês) para Cloudflare Pages (tier gratuito). Sim, gratuito. Nosso site está bem dentro dos limites do plano gratuito do Cloudflare — 500 builds por mês, banda ilimitada, requisições ilimitadas.
Cloudflare Pages faz deploy a partir de um Git push, serve de sua rede de edge global, e lida com cache headers automaticamente. Os tempos de build em média são 22 segundos para nosso site inteiro. Compare com nossa configuração WordPress onde uma purge de cache sozinha poderia levar mais tempo.
O custo mensal de hospedagem foi de $80 para $0.
Critical CSS Inlining
Astro automaticamente faz inline de pequenas stylesheets quando você seta build.inlineStylesheets: 'auto'. Para nossas páginas, cada estilo crítico é feito inline no <head>, significando que há zero requisições de CSS render-blocking. O navegador pode começar a pintar imediatamente.
Disciplina de Third-Party Script
Aqui é onde a maioria dos sites perde seus scores perfeitos. Cada third-party script é um potencial desastre de performance. Nós limitamos rigorosamente os nossos:
- Analytics: Trocamos de Google Analytics (70KB+ de JavaScript) para Plausible Analytics (< 1KB script, carregado async). Pagamos $9/mês para Plausible, e a qualidade dos dados é honestamente melhor para nossas necessidades.
- Forms: Nosso formulário de contato em /contact usa um simples formulário HTML com manipulação server-side via Cloudflare Pages Functions. Nenhuma biblioteca JavaScript de form.
- Sem chat widgets. Sem embeds de redes sociais. Sem banners de consentimento de cookie (não usamos cookies que requerem consentimento).
O Scorecard Lighthouse 100
Aqui estão nossos scores reais do Lighthouse a partir de maio de 2025, medidos usando Chrome DevTools em conexão throttled (simulação mobile padrão do Lighthouse):
| Métrica | Score |
|---|---|
| Performance | 100 |
| Acessibilidade | 100 |
| Melhores Práticas | 100 |
| SEO | 100 |
| First Contentful Paint | 0.6s |
| Largest Contentful Paint | 0.8s |
| Total Blocking Time | 0ms |
| Cumulative Layout Shift | 0 |
| Speed Index | 0.8s |
O Total Blocking Time de 0ms é minha estatística favorita. Zero. Essencialmente não há JavaScript bloqueando a main thread. Nunca.
Antes e Depois: Os Números
| Métrica | WordPress (Antes) | Astro (Depois) | Melhoria |
|---|---|---|---|
| Lighthouse Performance | 58 | 100 | +72% |
| LCP (mobile) | 2.4s | 0.8s | 3x mais rápido |
| CLS | 0.12 | 0 | Eliminado |
| TBT | 380ms | 0ms | Eliminado |
| Page weight (home) | 1.8MB | 142KB | 92% menor |
| HTTP requests | 47 | 6 | 87% menos |
| JavaScript enviado | 340KB | 2KB | 99.4% menos |
| Custo mensal de hosting | $80 | $9 (apenas Plausible) | 89% mais barato |
| Tempo de build/deploy | 3-5 min | 22 sec | ~10x mais rápido |
| Time to first byte | 420ms | 18ms | 23x mais rápido |
A redução de page weight é impressionante até para nós. 1.8MB para 142KB. É o que acontece quando você para de enviar jQuery, React, script loader do WP Rocket, injetor de schema markup do Yoast, e catorze stylesheets de plugins.
O Que Erramos Pelo Caminho
Não foi tudo tranquilo. Hora de ser honesto.
Erro 1: Quase Sobre-Engenheiramos o Content Management
Nosso primeiro instinto foi configurar Sanity como um CMS headless para o blog. Gastamos dois dias configurando schemas e configurando o Sanity Studio antes de dar um passo atrás e perguntar: "Quem na verdade vai usar isso?" A resposta era... nós. Desenvolvedores. Que estão perfeitamente felizes escrevendo MDX em VS Code. Ripsamos Sanity e fomos com Content Collections do Astro. Economizou custos contínuos e complexidade.
Erro 2: Font Subsetting Quebrou Caracteres Especiais
Nosso subset de fonte inicial foi muito agressivo. Cortamos caracteres que pensávamos nunca usar, então publicamos um post do blog com um em dash e algumas aspas curvas que renderizaram como caixas. Lição: teste seus subsets com conteúdo real, não apenas "ABCDEFG".
Erro 3: Esquecemos de OpenGraph Images
Lançamos sem imagens OG dinâmicas. Quando alguém compartilhava um post do blog no Twitter/X ou LinkedIn, mostrava um fallback genérico. Tivemos que voltar e construir um pipeline de geração de imagem OG usando @astrojs/og (que usa Satori por baixo). Deveria ter estado no escopo original.
Erro 4: O Mapa de Redirect 301 Tinha Lacunas
Apesar de usar Screaming Frog para mapear URLs antigas, perdemos algumas URLs de imagem que sites externos estavam hotlinkando. Pegamos essas em analytics do Cloudflare cerca de uma semana após o launch e adicionamos os redirects faltantes. Sempre verifique seus server logs após uma migração — Google Search Console não vai pegar tudo.
Lições Para Sua Própria Migração
Se você está considerando se mudar de WordPress para um framework estático-first, aqui está o que eu diria:
Audite antes de migrar. Mate conteúdo que não está performando. Uma migração é uma ótima oportunidade para podar.
Combine a ferramenta com o trabalho. Astro foi perfeito para nós porque somos principalmente conteúdo. Se você precisa de heavy interactivity, Next.js ou um framework similar pode ser o melhor.
Não faça cargo-cult de sua arquitetura antiga. Não tentamos replicar nossa configuração WordPress em Astro. Repensamos tudo do zero. Realmente precisamos de um plugin de form? Não, um elemento
<form>com uma função serverless funciona bem.Meça antes, meça depois, meça continuamente. Configuramos um job Lighthouse CI em GitHub Actions que roda em cada pull request. Se um PR derruba qualquer score abaixo de 95, ele falha a verificação.
Orçamente para os "últimos 5%". Chegar de Lighthouse 85 para 95 é direto. Chegar de 95 para 100 requer font subsetting, análise de critical CSS, otimização de formato de imagem, e auditoria de third-party script. Planeje tempo para isso.
Seus custos de hosting devem envergonhar sua configuração antiga. Se você está servindo arquivos estáticos e ainda pagando taxas significativas de hosting, algo está errado. Hosting estático é uma commodity agora.
Se você está interessado no que uma migração assim pareceria para seu projeto, confira nossa página de preços ou entre em contato. Fizemos esse caminho de migração para vários clientes agora, e os ganhos de performance são consistentemente dramáticos.
FAQ
Quanto tempo leva para migrar um site WordPress para Astro?
Para nosso site (cerca de 50 páginas incluindo posts do blog), levou aproximadamente 6 semanas de trabalho part-time. Um site maior com centenas de posts e tipos de post customizados complexos poderia levar 8-12 semanas. O desenvolvimento real é geralmente mais rápido do que a auditoria de conteúdo e mapeamento de redirects.
Você pode obter Lighthouse 100 com Next.js em vez de Astro?
É possível mas significativamente mais difícil. Next.js envia um runtime JavaScript para o navegador mesmo para páginas estáticas (a camada de React hydration). Você pode chegar perto — scores de 95-99 são alcançáveis com otimização cuidadosa. Mas a abordagem zero-JS-por-padrão do Astro torna scores perfeitos muito mais atingíveis para sites de conteúdo.
E quanto a funcionalidades do WordPress como formulários de contato e busca?
Formulários de contato funcionam bem com formulários HTML simples e um backend de função serverless (Cloudflare Pages Functions, Netlify Functions, etc.). Para busca, usamos uma busca client-side com Pagefind, que constrói um índice de busca no tempo de build e envia apenas 5KB de JavaScript. É rápido e funciona offline.
A migração de WordPress para Astro prejudica SEO?
Não se você fizer isso apropriadamente. Configuramos redirects 301 para cada URL, mantivemos nossa estrutura de URL quando possível, enviamos um novo sitemap, e mantivemos todos nosso structured data. Nosso tráfego orgânico realmente aumentou 23% nos três meses após migração, provavelmente devido aos Core Web Vitals melhorados.
Como você lida com conteúdo dinâmico como comentários em um site Astro?
Não temos comentários em nosso blog — eram principalmente spam no WordPress de qualquer forma. Se você precisa de comentários, serviços como Giscus (baseado em GitHub Discussions) ou Hyvor Talk funcionam bem como componentes embedidos. Eles carregam como ilhas Astro, então não afetam o carregamento inicial da página.
Astro está pronto para produção para sites grandes?
Absolutamente. Astro 5.x (lançado no final de 2024) é maduro e estável. Empresas como Porsche, Google, Microsoft, e Netlify a usam em produção. A performance de build também escala bem — sites com milhares de páginas constroem em menos de um minuto com a configuração certa.
Como é a manutenção contínua comparada com WordPress?
Dramaticamente menos. Sem atualizações de plugin, sem manutenção de banco de dados, sem patches de segurança para PHP. Atualizamos Astro e suas dependências talvez uma vez por mês via Dependabot PRs. Cada atualização leva cerca de 5 minutos para revisar e merge. Compare com a treadmill de atualização do WordPress.
Membros não-técnicos do time ainda podem editar conteúdo em um site Astro?
Com nossa configuração (arquivos MDX em Git), você precisa estar confortável com Markdown e workflows básicos de Git. Para times com editores não-técnicos, recomendamos parear Astro com um CMS headless como Sanity, Contentful, ou Storyblok. Os editores recebem uma interface visual, e você ainda recebe todos os benefícios de performance da geração estática.