# Spec — 032: Performance Homepage ## Identificação - **ID:** 032 - **Nome:** performance-homepage - **Prioridade:** Alta - **Tipo:** Refatoração / Otimização - **Dependências:** Nenhuma nova tabela ou endpoint. Apenas frontend. --- ## Problema A página inicial apresenta waterfall de requests, imagem hero sem priorização correta e re-renders desnecessários que degradam os Core Web Vitals (LCP, CLS, INP). Detalhes completos em [`performance-audit.md`](./performance-audit.md). --- ## Objetivo Atingir **LCP < 2.5 s**, **CLS < 0.1** e **INP < 150 ms** na página inicial sem alterar a aparência visual ou quebrar funcionalidades existentes. --- ## Escopo ### Incluído - Paralelização dos 3 fetches da home (`homepageConfig`, `featuredProperties`, `agents`) - Preload dinâmico da imagem hero quando URL estiver disponível - `fetchPriority="high"` + `loading="eager"` + `decoding="async"` na hero image - `loading="lazy"` nas imagens dos `PropertyRowCard` dentro da home - Mover `@keyframes fadeDown` de inline para `index.css` - `will-change: transform` no track do `AgentsCarousel` - Hook compartilhado `useInView` para `RiseCard` - Cache de `homepageConfig` em `sessionStorage` com TTL de 5 minutos - Skeleton de altura fixa na área hero para evitar CLS - `React.memo` em `PropertyRowCard` e `AgentSlide` - Consolidação de `resolvedTheme` / `isLight` para evitar chamada dupla ao `ThemeContext` ### Excluído - Mudanças no backend - Mudanças em outras páginas que não sejam dependências diretas - SSR / SSG - CDN ou otimização de infraestrutura - Bundle splitting (separado, escopo de build) --- ## Requisitos Funcionais | ID | Requisito | |---|---| | RF-01 | Todos os dados da home devem ser buscados em paralelo no mount de `HomePage` | | RF-02 | A imagem hero deve ter `fetchPriority="high"` quando `backgroundImage` estiver disponível | | RF-03 | Um `` deve ser inserido no `` assim que `backgroundImage` for resolvida | | RF-04 | As imagens dos cards de propriedades devem ter `loading="lazy"` | | RF-05 | `AgentsCarousel` deve receber `agents` e `loading` via props em vez de fazer fetch próprio | | RF-06 | `HomeScrollScene` deve receber `properties` e `loadingProperties` via props | | RF-07 | `homepageConfig` deve ser cacheado em `sessionStorage` por 5 minutos | | RF-08 | O skeleton da hero deve ter `min-height: 100svh` antes do config carregar para evitar CLS | --- ## Requisitos Não Funcionais | ID | Requisito | |---|---| | RNF-01 | LCP medido via Lighthouse deve ser < 2.5 s em conexão Fast 3G emulada | | RNF-02 | CLS deve ser < 0.1 | | RNF-03 | INP deve ser < 150 ms | | RNF-04 | Nenhuma regressão visual nos temas light e dark | | RNF-05 | Build TypeScript sem erros após todas as mudanças | | RNF-06 | Nenhuma mudança na API pública dos componentes exceto as necessárias para passar dados via props | --- ## Impacto em Componentes | Componente | Tipo de mudança | |---|---| | `HomePage.tsx` | Paralelizar fetches, preload, cache, passar props | | `HomeScrollScene.tsx` | Receber props de dados, mover keyframes, consolidar theme | | `AgentsCarousel.tsx` | Receber props em vez de fetch interno, will-change | | `PropertyRowCard.tsx` | `loading="lazy"` no `SlideImage` | | `index.css` | Adicionar `@keyframes fadeDown` | | `hooks/useInView.ts` | Criar hook novo | --- ## Critérios de Aceite - [ ] Lighthouse (Mobile, Fast 3G) reporta LCP < 2.5 s - [ ] Lighthouse reporta CLS < 0.1 - [ ] DevTools Network mostra os 3 fetches disparando simultaneamente - [ ] Segunda visita à home não faz request a `/homepage-config` dentro do TTL - [ ] Nenhum erro TypeScript (`npm run build` passa) - [ ] Tema light e dark funcionam visualmente como antes - [ ] `AgentsCarousel` e cards de destaque renderizam normalmente