# Skill: PageSpeed Optimizer

## Trigger
Use esta skill quando o usuário pedir para otimizar, revisar ou aumentar a pontuação de uma página no **PageSpeed Insights / Lighthouse** (mobile ou desktop). Exemplos:
- "otimize essa página para PageSpeed"
- "quero chegar em 85 no mobile"
- "revisa o pagespeed da landing"
- "/pagespeed-optimizer"

---

## Protocolo de Execução

### FASE 1 — Diagnóstico (OBRIGATÓRIO antes de qualquer mudança)

Antes de editar qualquer coisa, faça:

1. **Ler o arquivo HTML completo** com a ferramenta Read
2. **Identificar a plataforma** onde roda (GHL, WordPress, Webflow, HTML puro, etc.)
3. **Catalogar as métricas atuais** (pedir screenshot do PageSpeed ou perguntar os valores):
   - FCP (First Contentful Paint) — meta: < 1.8s
   - LCP (Largest Contentful Paint) — meta: < 2.5s
   - TBT (Total Blocking Time) — meta: < 200ms
   - CLS (Cumulative Layout Shift) — meta: < 0.1
   - Speed Index — meta: < 3.4s
4. **Identificar o LCP element** — o que o browser está medindo como maior conteúdo (imagem? h1? SVG?)
5. **Listar todos os scripts externos** carregados na página
6. **Auditar CSS** — verificar classes definidas vs. classes usadas no HTML

Só avançar para a Fase 2 após entender o diagnóstico.

---

### FASE 2 — Plano de Ataque (por prioridade de impacto)

Aplicar na ordem abaixo, do maior ao menor impacto:

#### PRIORIDADE 1 — Eliminar CLS (maior impacto em score)
→ Ver: [cls-fix.md](references/cls-fix.md)

- Identificar elemento causador do layout shift (PageSpeed mostra em "Causas da troca de layout")
- Se for **fonte web** (FOUT): mudar `display=swap` → `display=optional` + adicionar `@font-face` fallback com `size-adjust`
- Se for **imagem sem dimensões**: adicionar `width` e `height` explícitos
- Se for **GHL Full-Screen Fix JS**: usar double `requestAnimationFrame` para atrasar manipulação DOM

#### PRIORIDADE 2 — Fontes não-bloqueantes (FCP/LCP/CLS)
→ Ver: [fonts.md](references/fonts.md)

**Opção A — Self-hosting no Cloudinary (MÉTODO PREFERIDO, VALIDADO):**
- Hospedar woff2 latin-subset no Cloudinary (`resource_type=raw`)
- `<link rel="preconnect" href="https://res.cloudinary.com" crossorigin>` no topo
- `<link rel="preload" as="font" type="font/woff2" crossorigin href="...">` para cada fonte
- `@font-face` inline no CSS com `font-display: swap`
- Remover todo JS de carregamento de Google Fonts
- Resultado validado: CLS 0.227 → 0.078, TBT 450ms → 230ms, score 70 → **85 mobile**

**⚠️ ARMADILHA CRÍTICA — Nunca preload cross-origin:**
- Preload de `fonts.gstatic.com` compete com a imagem hero no 4G simulado
- Resultado testado: LCP 2.9s → 10.4s, score 70 → 42 (catastrófico)
- Só usar preload se fonte e imagem hero estiverem no MESMO domínio

**Opção B — Google Fonts async (quando Cloudinary não é opção):**
- Nunca usar `@import url(...)` dentro de `<style>` — bloqueia render 100%
- Usar `<link media="print" onload="this.media='all'">` para carregar fontes async
- Body font: `display=swap` | Heading/display: `display=optional`
- Adicionar `@font-face` fallback com `size-adjust` para cada fonte crítica

#### PRIORIDADE 3 — Eliminar CSS morto (TBT/parse time)
→ Ver: [css-audit.md](references/css-audit.md)

- Extrair todas as classes definidas no `<style>`
- Extrair todas as classes usadas no HTML (`class="..."`)
- Remover classes definidas mas nunca usadas
- Minificar o CSS restante (uma regra por linha, sem espaços desnecessários)
- Meta: reduzir `<style>` em pelo menos 50%

#### PRIORIDADE 4 — Imagens otimizadas
→ Ver: [images.md](references/images.md)

- Formato: WebP obrigatório (`f_webp` no Cloudinary)
- Qualidade: `q_auto:good` (Cloudinary) ou equivalente
- Dimensões: nunca carregar imagem maior que o espaço visual dela
- `loading="lazy"` + `decoding="async"` em imagens abaixo do fold
- LCP image: adicionar `fetchpriority="high"` + NUNCA lazy load
- `srcset` + `sizes` para responsividade real
- `width` e `height` explícitos para evitar CLS

#### PRIORIDADE 5 — Eliminar efeitos GPU no mobile
→ Ver: [mobile-gpu.md](references/mobile-gpu.md)

- Mover animações CSS para `@media(min-width:1024px)` — mobile não executa
- `backdrop-filter: blur()` apenas em desktop
- `box-shadow` pesados: mover para desktop ou simplificar no mobile
- `background: radial-gradient` decorativos: `display:none` no mobile
- `contain: layout style` em containers grandes — isola reflows

#### PRIORIDADE 6 — Reduzir DOM (TBT)

- Elementos repetidos para animação (ticker/tape): usar mínimo de nós
- Para efeito de scroll infinito: 2 cópias são suficientes (o CSS cuida do loop)
- Cada cópia: máximo 4-6 itens de texto (não 8+)
- Remover atributos inline redundantes quando a classe CSS já cobre

#### PRIORIDADE 7 — Scripts eficientes (TBT)

- `GHL_CONFIG` como objeto único de configuração — sem lógica pesada no parse
- UTM capture: IIFE simples, sem loops complexos
- Form submit: apenas um event listener, sem manipulações DOM custosas
- Meta Pixel: só injetar se `metaPixelId` estiver preenchido (condicional)
- Scripts de terceiros incontroláveis (GTM, TikTok Pixel): TBT residual inevitável — documentar

---

### FASE 3 — Execução

1. Aplicar as otimizações na ordem de prioridade
2. A cada mudança, verificar que não quebra funcionalidade
3. Manter comentários explicativos onde a lógica não for óbvia
4. Nunca remover: GHL_CONFIG, webhook URL, redirects, UTM capture, Meta Pixel conditional

---

### FASE 4 — Validação e Próximos Passos

Ao terminar, reportar:
- Lista de todas as mudanças aplicadas
- Estimativa de impacto por métrica
- O que ainda está fora do controle (scripts de terceiros)
- Score esperado após as mudanças

---

## Limites Reais (o que NÃO dá para controlar)

| Fator | Impacto | Solução |
|-------|---------|---------|
| GTM injetado pelo GHL | +150-250ms TBT | Nenhuma — fora do nosso HTML |
| TikTok Pixel do GHL | +50-100ms TBT | Nenhuma — fora do nosso HTML |
| Google Fonts latência | +100-300ms FCP | Preconnect + async load (minimiza) |
| Variabilidade do Lighthouse | ±5 pontos | Testar 3x e usar mediana |
| Throttling 4G simulado | Multiplica tudo | Base do teste, não controlável |

**Teto realista no GHL com scripts externos:** ~83-87 mobile (validado: 85 com self-hosting de fontes no Cloudinary)

| Fator | Impacto no TBT | Solução |
|-------|---------|---------|
| GHL CSS (leadconnectorhq.com) | +800-1400ms TBT **desktop** | Nenhuma — fora do nosso HTML |
| GTM injetado pelo GHL | +100-150ms TBT mobile | Nenhuma — fora do nosso HTML |
| TikTok Pixel do GHL | +50-100ms TBT | Nenhuma — fora do nosso HTML |
| Google Fonts latência | CLS +0.15, FCP +200ms | → Self-host no Cloudinary |
| Variabilidade do Lighthouse | ±5 pontos | Testar 3x e usar mediana |

**Atenção desktop vs mobile**: Desktop tende a ter TBT muito maior (+1000ms) por causa do GHL CSS — isso é normal e não indica problema no nosso HTML. Mobile é a métrica relevante para score.

---

## Referências

- [cls-fix.md](references/cls-fix.md) — Como eliminar CLS causado por fontes, imagens e JS
- [fonts.md](references/fonts.md) — Estratégia completa de carregamento de fontes
- [css-audit.md](references/css-audit.md) — Como auditar e eliminar CSS morto
- [images.md](references/images.md) — Otimização de imagens para PageSpeed
- [mobile-gpu.md](references/mobile-gpu.md) — Eliminar efeitos custosos no mobile
- [ghl-specifics.md](references/ghl-specifics.md) — Peculiaridades do GHL e soluções validadas
