# Auditoria de Performance — Página Inicial (Home) > Versão: 1.0 · Data: 2026-04-22 > Escopo: `HomePage.tsx`, `HomeScrollScene.tsx`, `AgentsCarousel.tsx`, `PropertyRowCard.tsx`, `Navbar.tsx` --- ## 1. Resumo Executivo A página inicial é a mais crítica em termos de first impression e conversão. A análise identificou **5 categorias de problemas** que impactam diretamente o Core Web Vitals (LCP, CLS, INP) e a experiência percebida do usuário: | Categoria | Severidade | Impacto estimado no LCP | |---|---|---| | Requests em cascata (waterfall) | 🔴 Alta | +600–1200 ms | | Imagem hero sem preload / sem dimensões | 🔴 Alta | +800–1500 ms | | Scroll scene: `useTheme` + re-renders desnecessários | 🟡 Média | +60–150 ms INP | | AgentsCarousel: autoplay sem `requestAnimationFrame` | 🟡 Média | jank visual | | `RiseCard`: IntersectionObserver por instância | 🟢 Baixa | +n×2 ms compositing | --- ## 2. Problemas Identificados ### 2.1 Waterfall de Requests (Crítico) **Arquivo:** `HomePage.tsx` + `HomeScrollScene.tsx` **Problema atual:** ``` Render HomePage └─ useEffect: getHomepageConfig() ← request 1 (bloqueia backgroundImage) └─ setState(config) → re-render └─ HomeScrollScene recebe props └─ useEffect: getFeaturedProperties() ← request 2 só começa AQUI └─ useEffect: getAgents() ← request 3 só começa APÓS mount ``` Os três requests são **seriais por dependência de render**: `getAgents` e `getFeaturedProperties` só disparam após `HomeScrollScene` montar, que depende do render de `HomePage`, que depende de `getHomepageConfig`. **Impacto:** Em conexões 3G, o usuário espera 3× o RTT antes de ver qualquer conteúdo real. LCP pode ultrapassar 4 s. **Solução:** Paralelizar os três fetches no topo de `HomePage` com `Promise.all` e passar dados via props. --- ### 2.2 Hero Image sem `` e sem width/height (Crítico) **Arquivo:** `HomeScrollScene.tsx`, linha da tag `` **Problema atual:** ```tsx ``` - Sem `width`/`height` → o browser não reserva espaço → **CLS** quando a imagem carrega - Sem `` no `` → a imagem começa a baixar somente quando o React renderiza o componente, não durante o parse do HTML - Sem `fetchpriority="high"` → browser não prioriza sobre outros assets - Sem `loading="eager"` explícito → comportamento depende do browser **Impacto:** LCP degradado. Em telas de 1080p com imagem de 1 MB, o atraso pode ser de 1–2 s adicionais. **Solução:** 1. Adicionar `fetchpriority="high"` e `loading="eager"` na tag `` 2. Injetar `` dinamicamente via `useEffect` assim que `backgroundImage` estiver disponível (ou via ``) --- ### 2.3 `useTheme` sendo chamado duas vezes para o mesmo dado **Arquivos:** `HomePage.tsx` e `HomeScrollScene.tsx` **Problema atual:** ```tsx // HomePage.tsx const { resolvedTheme } = useTheme() const themedBackgroundImage = resolvedTheme === 'dark' ? ... : ... // HomeScrollScene.tsx (recebe backgroundImage, mas chama useTheme DE NOVO) const { resolvedTheme } = useTheme() const isLight = resolvedTheme === 'light' ``` `resolvedTheme` é derivado duas vezes. Qualquer mudança de tema causa re-render em dois componentes separados com lógica duplicada. Além disso, `HomeScrollScene` não precisa conhecer o tema se receber `backgroundImage` já resolvida pelo pai — mas ainda usa `isLight` para estilos internos, o que é legítimo. O problema é a derivação `themedBackgroundImage` estar fora do componente que a consome. **Solução:** Manter `isLight` em `HomeScrollScene` (necessário para estilos), mas mover `themedBackgroundImage` para dentro de `HomeScrollScene` eliminando a prop intermediária e a chamada dupla ao context em `HomePage`. --- ### 2.4 `AgentsCarousel`: `setInterval` sem cleanup confiável + CSS transform sem `will-change` **Arquivo:** `AgentsCarousel.tsx` **Problema atual:** ```tsx const autoplayRef = useRef | null>(null) // ...sem uso de requestAnimationFrame // CSS translate via inline style, sem will-change: transform ``` - `setInterval` para animação de scroll não é sincronizado com o frame rate do browser → pode causar jank em displays 120 Hz - Ausência de `will-change: transform` no track → o browser não promove a camada para GPU antes da primeira animação → primeiro frame pode ser janky - Duplicação de slides (`[...agents, ...agents]`) sem `key` estável baseada em `agent.id` único (usa índice implicitamente) --- ### 2.5 `RiseCard`: IntersectionObserver por instância sem threshold otimizado **Arquivo:** `HomeScrollScene.tsx` **Problema atual:** ```tsx // Cria 1 IntersectionObserver por card (até 6+ na home) const observer = new IntersectionObserver(([entry]) => { if (entry.isIntersecting) { setVisible(true) observer.disconnect() } }, { threshold: 0.05 }) ``` Cada `RiseCard` instancia seu próprio `IntersectionObserver`. Com 6 cards, são 6 observers ativos simultaneamente. O ideal é um único observer compartilhado (padrão singleton/context) que observa todos os elementos. **Impacto:** Pequeno em volume baixo, mas escala mal. 6 observers × scroll events = trabalho desnecessário na main thread. --- ### 2.6 ` ``` Isso insere uma tag `