Skip to content

Otimização de Performance

Cenários reais para encontrar e corrigir problemas de performance.

Carregamento Lento de Página

Objetivo: Reduzir o carregamento inicial da página de 5s para menos de 1s.

Comando:

Optimize the dashboard page — it takes 5 seconds to load

O que acontece:

  1. Perfilar — Mede as métricas atuais (LCP, FID, CLS)
  2. Analisar — Identifica gargalos (tamanho do bundle, chamadas de API, renders)
  3. Otimizar — Aplica correções direcionadas
  4. Verificar — Mede a melhoria com evidências

Resultado:

Performance: Dashboard Optimization

PROFILE
  LCP: 4.8s (poor)
  FID: 320ms (needs improvement)
  Bundle: 2.1MB (too large)
  API calls on mount: 8 parallel requests

BOTTLENECKS
  1. Single bundle (no code splitting)
  2. All 8 API calls block render
  3. Heavy chart library loaded eagerly

OPTIMIZE
  1. Dynamic import for chart component
     - const Chart = lazy(() => import('./Chart'))
  2. Parallel data fetching with Suspense
  3. Route-based code splitting

VERIFIED
  LCP: 1.1s → 0.8s (good)
  FID: 80ms (good)
  Bundle: 420KB initial (80% reduction)

Query de Banco de Dados

Objetivo: Corrigir endpoint de API lento (2s de tempo de resposta).

Comando:

Optimize the /api/products endpoint — it takes 2 seconds to respond

Resultado:

Performance: API Endpoint Optimization

PROFILE
  GET /api/products: avg 2.1s
  Database query: 1.8s (bottleneck)
  Query: SELECT * FROM products JOIN categories...

ANALYZE
  1. Missing index on products.category_id
  2. SELECT * fetches 25 unused columns
  3. No pagination (returns all 50k rows)

OPTIMIZE
  1. CREATE INDEX idx_products_category ON products(category_id)
  2. SELECT only needed columns
  3. Add cursor-based pagination (limit 20)

VERIFIED
  GET /api/products: avg 45ms (97% improvement)
  Query plan: Index Scan (was Seq Scan)

Tamanho do Bundle

Objetivo: Reduzir o tamanho do bundle JavaScript.

Comando:

Analyze and reduce the bundle size — it's over 2MB

Resultado:

Performance: Bundle Optimization

PROFILE
  Total: 2.3MB
  Largest chunks:
    - moment.js: 480KB (with all locales)
    - lodash: 320KB (full import)
    - chart.js: 290KB

OPTIMIZE
  1. moment.js → date-fns (tree-shakeable)
     480KB → 12KB
  2. import _ from 'lodash' → import { debounce } from 'lodash-es'
     320KB → 4KB
  3. Dynamic import for charts (only on dashboard)
     290KB → 0KB initial

VERIFIED
  Total: 580KB (75% reduction)
  Lighthouse Performance: 92 (was 48)

Performance de Renderização

Objetivo: Corrigir scroll travado em uma lista longa.

Comando:

Optimize the product list — scrolling is janky with 10k items

Resultado:

Performance: List Virtualization

PROFILE
  DOM nodes: 10,000 rows × 8 columns = 80,000 nodes
  Scroll FPS: 12 (target: 60)
  Layout recalculations: constant

ANALYZE
  Rendering all 10k rows at once
  No virtualization
  Each row has complex child components

OPTIMIZE
  import { useVirtualizer } from '@tanstack/react-virtual'

  const virtualizer = useVirtualizer({
    count: products.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 48,
    overscan: 5,
  })

  // Render only visible rows (~20 instead of 10,000)

VERIFIED
  DOM nodes: ~200 (99.7% reduction)
  Scroll FPS: 60 (smooth)
  Memory: 45MB → 12MB

Dicas Rápidas

Meça Primeiro

# Não adivinhe — meça
Analyze the performance of /api/orders endpoint

# Inclua o sintoma
The dashboard takes 3 seconds to load after login

Ganhos Comuns

ProblemaSolução
Bundle grandeCode splitting + tree shaking
Queries lentasIndexes + paginação
Muitos re-rendersMemoização + virtualização
API lentaCaching + requisições paralelas

Cenários Relacionados

Publicado sob a Licença MIT.