feat: features 025-032 - favoritos, contatos, trabalhe-conosco, area-cliente, navbar, hero-light-dark, performance-homepage
- feat(025): favoritos locais com FavoritesContext, HeartButton, PublicFavoritesPage
- feat(026): central de contatos admin (leads/contatos unificados)
- feat(027): configuração da página de contato via admin
- feat(028): trabalhe conosco - candidaturas com upload e admin
- feat(029): UX área do cliente - visitas, comparação, perfil
- feat(030): navbar UX - menu mobile, ThemeToggle, useFavorites
- feat(031): hero light/dark - imagens separadas por tema, upload, preview, seed
- feat(032): performance homepage - Promise.all parallel fetches, sessionStorage cache,
preload hero image, loading=lazy nos cards, useInView hook, will-change carrossel,
keyframes em index.css, AgentsCarousel e HomeScrollScene via props
- fix: light mode HomeScrollScene - gradiente, cores de texto, scroll hint
migrations: g1h2i3j4k5l6 (source em leads), h1i2j3k4l5m6 (contact_config),
i1j2k3l4m5n6 (job_applications), j2k3l4m5n6o7 (hero theme images)
This commit is contained in:
parent
6ef5a7a17e
commit
cf5603243c
106 changed files with 11927 additions and 1367 deletions
97
specs/032-performance-homepage/spec.md
Normal file
97
specs/032-performance-homepage/spec.md
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
# 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 `<link rel="preload">` deve ser inserido no `<head>` 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue