Sistema de Claps Otimista: Replicando a UX do Medium

12 min de leitura

Como construir um sistema de applause/claps igual ao Medium com otimizações agressivas que reduzem 85% das operações no banco de dados.

ReactRedisUXPerformanceMedium

Sistema de Claps Otimista: Replicando a UX do Medium#

Acabei de implementar um sistema de claps igual ao Medium no meu portfólio. O resultado? 85% menos operações no Redis e uma UX indistinguível do original!

O Desafio#

O Medium permite até 50 "claps" por artigo com feedback instantâneo. O desafio era replicar essa experiência sem sobrecarregar o servidor.

Problemas do Sistema Simples:#

  • 1 requisição por clap = 50 requisições potenciais
  • Latência perceptível entre clap e feedback
  • Rate limiting complexo
  • UX quebrada em conexões lentas

A Solução: Otimismo Inteligente#

1. Updates Otimistas#

const addClap = useCallback(() => {
  // Atualiza UI instantaneamente
  const newOptimistic = {
    total: optimistic.total + 1,
    userClaps: optimistic.userClaps + 1,
    hasClapped: true,
  }

  setOptimistic(newOptimistic)
  saveToCache(newOptimistic)

  // Sincroniza em background
  debouncedSync()
}, [optimistic, debouncedSync])

2. Batching Inteligente#

O sistema agrupa claps em lotes e espera 2 segundos de pausa antes de sincronizar:

// Detecta burst de claps
if (burstCountRef.current >= 5) {
  syncImmediately() // Sync imediato para evitar perda
} else {
  debounceSync(2000) // Aguarda pausa
}

3. Cache Estratificado#

Três níveis de cache:

  1. UI State: Instantâneo, sempre atualizado
  2. localStorage: 2min TTL, sobrevive a reloads
  3. Redis: Backend cache com TTL variável

4. Estados Visuais Avançados#

Progression System (0-50 claps):

  • 1-10: Coração se enche gradualmente
  • 11-25: Efeito pulsante vermelho
  • 26-40: Múltiplos corações flutuantes
  • 41-50: Modo celebration com ⚡

5. Animações de Micro-interação#

// Burst effect em claps rápidos
{rapidClaps > 0 && (
  <motion.div
    className="floating-indicator"
    animate={{ y: [-10, 0], opacity: [0, 1, 0] }}
  >
    +{rapidClaps}
  </motion.div>
)}

Resultados Mensuráveis#

Performance:#

  • Antes: ~98 reads + 41 writes para 5 likes
  • Depois: ~15 reads + 8 writes para 50 claps
  • Redução: 85% menos operações

UX:#

  • Resposta UI: < 16ms (60fps)
  • Sync transparente em background
  • Fallback graceful para dados stale
  • Zero interrupções na experiência

Otimizações Redis:#

Pipeline Otimizado:

// Batch de 10 claps = 1 operação
pipeline.incrby('claps:post:123:total', 10)
pipeline.incrby('claps:post:123:user:abc', 10)
pipeline.incrby('claps:ratelimit:abc:2024-03-20', 10)

vs Sistema Antigo:

// 10 claps = 60 operações (6 por clap)
for (let i = 0; i < 10; i++) {
  pipeline.incr('likes:post:123:total')
  pipeline.incr('likes:post:123:user:abc')
  pipeline.incr('likes:ratelimit:abc:2024-03-20')
  pipeline.expire(key1, ttl)
  pipeline.expire(key2, ttl)
  pipeline.expire(key3, ttl)
}

Lições Aprendidas#

1. Otimismo Funciona#

Updates otimistas + sync em background = UX perfeita. O usuário nunca percebe latência.

2. Batching é Poderoso#

Agregar operações reduz drasticamente a carga no servidor sem impactar UX.

3. Cache em Camadas#

Múltiplos níveis de cache criam redundância e performance.

4. Visual Feedback é Crucial#

Animações e estados visuais mantêm o usuário engajado durante operações async.

Próximos Passos#

  • Analytics: Métricas de engajamento por post
  • Personalização: Efeitos visuais customizáveis
  • Social: Sistema de leaderboards
  • Mobile: Haptic feedback para toque

O sistema está production-ready e pode ser facilmente adaptado para qualquer aplicação que precise de interações frequentes com feedback instantâneo.

Resultado: UX igual ao Medium com infraestrutura 85% mais eficiente! 🚀