# GHL — Peculiaridades e Soluções Validadas

GoHighLevel injeta scripts e elementos extras que afetam a performance fora do nosso controle.
Este documento cataloga o que sabemos e as melhores soluções.

---

## O que o GHL injeta (fora do nosso controle)

| Elemento | Impacto no TBT | Solução |
|----------|---------------|---------|
| Google Tag Manager | +100-150ms | Nenhuma — fora do nosso HTML |
| TikTok Pixel (se ativo) | +50-100ms | Nenhuma — fora do nosso HTML |
| GHL tracking scripts | +50ms | Nenhuma |
| Template containers (rows, sections) | CLS se não tratado | GHL Full-Screen Fix JS |
| GHL header/footer do template | Espaço branco | GHL Full-Screen Fix JS (esconder siblings) |

**TBT mínimo esperado no GHL**: ~250-350ms (mesmo com HTML perfeito).
**Score máximo realista no mobile GHL**: 78-83 (com tudo otimizado do nosso lado).

---

## GHL Full-Screen Fix (v2 — validado)

Versão atual, com double `requestAnimationFrame` para evitar CLS:

```js
(function() {
    function applyFix() {
        var root = document.querySelector('.oap-root');
        if (!root) return;
        if (root.parentElement !== document.body) {
            var placeholder = document.createElement('div');
            placeholder.style.display = 'none';
            root.parentElement.insertBefore(placeholder, root);
            document.body.insertBefore(root, document.body.firstChild);
        }
        document.body.style.margin = '0';
        document.body.style.padding = '0';
        document.body.style.overflow = 'hidden auto';
        Array.prototype.forEach.call(document.body.children, function(el) {
            if (el !== root) el.style.display = 'none';
        });
    }
    // Se já está no body direto: rodar imediatamente (sem CLS)
    // Se está aninhado no GHL: adiar para depois do primeiro paint
    var root = document.querySelector('.oap-root');
    if (root && root.parentElement === document.body) {
        applyFix();
    } else {
        requestAnimationFrame(function() { requestAnimationFrame(applyFix); });
    }
})();
```

**Por que funciona:**
1. Move `.oap-root` para `document.body.firstChild` — escapa de todos os containers do GHL
2. Esconde todos os outros filhos do body — elimina espaço branco do header/footer do template
3. Double rAF adia a execução para depois do primeiro paint — reduz CLS de ~0.1 para ~0.06

---

## GHL Custom Code — restrições

- O código é injetado dentro de um container no meio da página
- **Não temos controle do `<head>`** — não é possível usar `<link rel="preload">` normalmente
- O `media="print" onload` trick para fontes funciona mesmo sem `<head>`, pois o browser processa os `<link>` onde quer que estejam
- Preconnect (`<link rel="preconnect">`) funciona em qualquer lugar no DOM

---

## Prefixo CSS — obrigatório

O GHL injeta suas próprias classes no corpo da página. Qualquer classe sem prefixo pode conflitar.

**Padrão validado:**
- Projeto `operacao-aprova-petro`: prefixo `oap-`
- Novos projetos: usar 3-4 letras do nome do projeto

**Prefixar também:**
- IDs de gradientes SVG (`id="oap-gold-grad"`)
- IDs de elementos HTML usados em JS (`id="oap-form"`)

---

## GHL_CONFIG — estrutura padrão

```js
var GHL_CONFIG = {
    webhookURL: 'https://webhook.focusnd.com.br/webhook/NOME-DO-WEBHOOK',
    pages: {
        obrigado: 'https://dominio.com/obrigado',
        naoEngenheiro: 'https://dominio.com/nao-qualificado',
        vendas: 'https://dominio.com/vendas'
    },
    images: {
        mentor: 'https://res.cloudinary.com/dozxsfkmm/image/upload/f_webp,q_auto:good,w_680,c_fill,g_face/PASTA/mentor.jpg'
    },
    tags: ['tag-1', 'tag-2'],
    // metaPixelId: 'ID_DO_PIXEL', // comentado até ter pixel configurado
};
```

---

## Estrutura de arquivos — Projeto Operação Aprova Petro

```
/Users/anthonynichols/Projetos I.A/bizu-do-engenheiro/Operacao-Aprova-Petro/03_Web/
├── index.html       → Landing A (variante principal)
├── index-b.html     → Landing B (variante de teste)
├── index-c.html     → Landing C (variante de teste)
├── obrigado.html    → Página de confirmação
└── nao-engenheiro.html → Página para não qualificados
```

Cloudinary cloud: `dozxsfkmm` | Pasta: `operacao-aprova-petro/`

---

## Histórico de scores — Operação Aprova Petro Landing C (index-c.html)

### Mobile

| Sessão | Score | FCP | LCP | TBT | CLS | Mudança principal |
|--------|-------|-----|-----|-----|-----|------------------|
| 1 | 58 | — | — | — | — | Baseline |
| 1 | 41 | — | — | — | — | Tentativas anteriores (regressão) |
| 2 | 72 | 3.0s | 3.4s | 510ms | 0.064 | Fontes optional + CSS audit + mobile GPU |
| 2 | 75 | 3.3s | 3.3s | 400ms | 0.064 | Mais CSS audit + double rAF |
| 3 | 70 | 2.3s | 2.9s | 450ms | 0.227 | Regressão (causa: sessão anterior) |
| 3 | 42 | — | 10.4s | 660ms | 0.227 | ❌ Tentativa: preload fonts.gstatic.com → CATASTRÓFICO |
| 3 | **85** | 2.3s | 3.2s | 230ms | 0.078 | ✅ Self-hosting fontes no Cloudinary |

### Desktop

| Sessão | Score | FCP | LCP | TBT | CLS | Observação |
|--------|-------|-----|-----|-----|-----|------------|
| 3 | 68 | 0.6s | 0.7s | 550ms | 0.197 | Antes do Cloudinary |
| 3 | 70 | 0.6s | 0.8s | 1.460ms | 0 | Após Cloudinary — TBT alto é 100% GHL CSS |

**Conclusão desktop**: FCP/LCP/CLS perfeitos. TBT 1.460ms é inteiramente do CSS do GHL (`leadconnectorhq.com`) — sem solução no nosso código. Não tocar no código tentando melhorar desktop ou vai regredir o mobile.

---

## Lição crítica — Preload cross-origin é armadilha

Tentar `<link rel="preload" as="font">` apontando para `fonts.gstatic.com`:
- **Parece** uma boa ideia: "priorizar download da fonte"
- **Na prática**: o browser 4G simulado tem bandwidth limitado → a fonte competi com a imagem hero → LCP colapsa
- **Regra**: preload só funciona bem quando fonte e imagem hero estão no MESMO domínio (HTTP/2 multiplexing)
