Padrões de interface em tempo real
Aplicar atualizações otimistas para obter feedback imediato, utilizar filas locais quando estiver offline e comparar os dados recebidos para atualizar apenas os itens alterados na interface.
Padrões de interface em tempo real é uma aula grátis de Frontend Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Frontend Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Frontend Academy inclui 4 aulas no total.
Tempo real significa uma UX realmente responsiva
Tempo real é mais do que rapidez: significa ser responsivo, previsível e tolerante à latência. Há três padrões principais: atualizações otimistas, enfileiramento local e comparação inteligente de diferenças.
Atualizações otimistas
Atualize a interface imediatamente após a ação do usuário, antes da confirmação do servidor. Reverta a alteração se o servidor a rejeitar. Isso faz os aplicativos parecerem instantâneos.
async function likePost(id) {
// 1. Optimistically update UI:
setLikes(l => ({ ...l, [id]: (l[id] || 0) + 1 }));
setLiked(prev => ({ ...prev, [id]: true }));
try {
await fetch(`/api/posts/${id}/like`, { method: 'POST' });
} catch (err) {
// 2. Rollback on failure:
setLikes(l => ({ ...l, [id]: (l[id] || 1) - 1 }));
setLiked(prev => ({ ...prev, [id]: false }));
toast.error('Could not like — please retry');
}
}Atualizações otimistas com IDs temporários
Para itens criados, atribua localmente um ID temporário. Substitua-o pelo ID real do servidor quando a resposta chegar.
async function addComment(text) {
const tempId = `tmp-${Date.now()}`;
setComments(c => [...c, { id: tempId, text, pending: true }]);
try {
const saved = await fetch('/api/comments', {
method: 'POST',
body: JSON.stringify({ text })
}).then(r => r.json());
setComments(c => c.map(m => m.id === tempId ? saved : m));
} catch (err) {
setComments(c => c.map(m => m.id === tempId ? { ...m, error: true } : m));
}
}Enfileiramento local quando estiver offline
Quando a rede estiver indisponível, enfileire as ações localmente e reproduza-as quando ela voltar. O usuário poderá continuar trabalhando.
const queue = JSON.parse(localStorage.getItem('queue') || '[]');
function enqueue(action) {
queue.push(action);
localStorage.setItem('queue', JSON.stringify(queue));
trySend();
}
async function trySend() {
while (queue.length && navigator.onLine) {
const action = queue[0];
try {
await fetch(action.url, action);
queue.shift();
localStorage.setItem('queue', JSON.stringify(queue));
} catch {
break; // stop until online
}
}
}
window.addEventListener('online', trySend);Comparando dados recebidos em tempo real
Se o servidor enviar a lista inteira, compare-a com o estado atual e atualize somente as alterações; assim, você evita novas renderizações desnecessárias e falhas nas animações.
function applyServerSnapshot(newList, currentList) {
const current = new Map(currentList.map(i => [i.id, i]));
const result = newList.map(item => {
const prev = current.get(item.id);
if (!prev) return { ...item, _state: 'new' };
if (prev.updatedAt !== item.updatedAt) return { ...item, _state: 'updated' };
return prev;
});
return result;
}Atualizações baseadas em patches
São melhores do que snapshots completos: o servidor envia somente os campos alterados. Aplique-os de forma incremental; isso utiliza menos largura de banda e é mais rápido de renderizar.
// Server sends: { type: 'patch', id: 42, fields: { likes: 11 } }
ws.on('message', (msg) => {
if (msg.type === 'patch') {
setPosts(posts => posts.map(p =>
p.id === msg.id ? { ...p, ...msg.fields } : p
));
}
});Limitando atualizações de alta frequência
Alguns fluxos enviam muitas atualizações por segundo (posição do mouse e cotações de ações). Limite as atualizações da interface a aproximadamente 60 Hz para evitar travamentos no navegador.
import { throttle } from 'lodash-es';
const applyUpdate = throttle((data) => {
setData(data);
}, 16); // ~60fps
ws.on('tick', applyUpdate);Indicadores de presença
Mostre quem mais está online ou digitando em tempo real. O servidor publica eventos de presença; o cliente renderiza uma lista com avatares.
ws.on('presence', ({ users }) => {
setOnlineUsers(users);
});
ws.on('typing', ({ user, isTyping }) => {
setTypingUsers(t => isTyping
? [...t.filter(u => u.id !== user.id), user]
: t.filter(u => u.id !== user.id));
});Banner do estado da conexão
Mostre um banner discreto quando estiver offline ou reconectando. Oculte-o após a reconexão completa. Os usuários toleram muito melhor a latência quando conseguem ver o que está acontecendo.
{!isConnected && (
<div className="connection-banner">
Reconnecting... Your changes will sync when you're back online.
</div>
)}Resolução de conflitos
Aplicativos em tempo real precisam lidar com edições simultâneas conflitantes. Estratégias: vence a última gravação (simples, mas com perda de dados), vetores de versão, OT (transformação operacional) e CRDTs (Yjs, Automerge).
CRDTs para colaboração
CRDTs (tipos de dados replicados sem conflitos) permitem a edição colaborativa em tempo real sem um servidor central. Bibliotecas: Yjs e Automerge. São usados por aplicativos no estilo do Figma, Linear e Notion.
Desempenho: listas virtualizadas
Os feeds em tempo real podem ficar longos. Use listas virtualizadas (react-virtuoso, @tanstack/react-virtual) para renderizar somente os itens visíveis; assim, o uso de memória e CPU permanece fixo, independentemente da quantidade total.
Verificação rápida
O que é uma 'atualização otimista' em uma interface em tempo real?
Recapitulação: padrões de interfaces em tempo real
Atualizações otimistas fazem os aplicativos parecerem instantâneos; reverta-as em caso de falha. Use IDs temporários para itens criados. Use enfileiramento local para garantir a durabilidade quando estiver offline. Compare ou aplique patches às atualizações do servidor para evitar novas renderizações. Limite fluxos de alta frequência. Mostre a presença (online e digitando) e banners de conexão. Use CRDTs (Yjs e Automerge) para edição colaborativa. Virtualize listas longas em tempo real.
Perguntas Frequentes
A aula “Padrões de interface em tempo real” é grátis?
Sim — o texto completo de “Padrões de interface em tempo real” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Frontend Academy, atualize para CoddyKit PRO. O curso de Frontend Academy inclui 4 aulas no total.
O que vou aprender em “Padrões de interface em tempo real”?
Aplicar atualizações otimistas para obter feedback imediato, utilizar filas locais quando estiver offline e comparar os dados recebidos para atualizar apenas os itens alterados na interface. Você pratica Frontend Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Frontend Academy?
Nenhuma experiência prévia é necessária. Frontend Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Padrões de interface em tempo real”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Frontend Academy?
Sim. Cada aula de Frontend Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- API WebSocket: abrir, mensagem, fechar e erro
- Integração do cliente Socket.io
- Eventos enviados pelo servidor para transmissão unidirecional
- Padrões de interface em tempo real