Schemi per interfacce in tempo reale
Applicare aggiornamenti ottimistici per un feedback immediato, usare code locali quando si è offline e confrontare i dati in arrivo per aggiornare nell’interfaccia solo gli elementi modificati
Schemi per interfacce in tempo reale è una lezione Frontend Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Frontend Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Frontend Academy include 4 lezioni in totale.
Il tempo reale significa un'esperienza davvero reattiva
Il tempo reale non significa solo rapidità: significa anche reattività, prevedibilità e capacità di gestire la latenza. I tre schemi fondamentali sono: aggiornamenti ottimistici, accodamento locale e confronto intelligente delle differenze.
Aggiornamenti ottimistici
Aggiorni subito l'interfaccia in risposta all'azione dell'utente, prima della conferma del server. Ripristini lo stato precedente se il server rifiuta l'operazione. In questo modo l'applicazione sembra istantanea.
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');
}
}Aggiornamenti ottimistici con ID temporanei
Per gli elementi creati, assegni loro localmente un ID temporaneo. Lo sostituisca con l'ID reale del server quando arriva la risposta.
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));
}
}Accodamento locale quando si è offline
Quando la rete non è disponibile, accodi le azioni localmente e le esegua nuovamente quando la connessione torna disponibile. L'utente può continuare a lavorare.
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);Confrontare i dati in tempo reale in arrivo
Se il server invia l'intero elenco, lo confronti con lo stato corrente e aggiorni solo le modifiche: evita renderizzazioni non necessarie e problemi con le animazioni.
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;
}Aggiornamenti basati su patch
È meglio delle snapshot complete: il server invia solo i campi modificati. Applichi gli aggiornamenti in modo incrementale: utilizza meno banda ed è più rapido da visualizzare.
// 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
));
}
});Limitare gli aggiornamenti ad alta frequenza
Alcuni flussi inviano molti aggiornamenti al secondo (posizione del mouse, variazioni delle quotazioni). Limiti gli aggiornamenti dell'interfaccia a circa 60 Hz per evitare rallentamenti nel browser.
import { throttle } from 'lodash-es';
const applyUpdate = throttle((data) => {
setData(data);
}, 16); // ~60fps
ws.on('tick', applyUpdate);Indicatori di presenza
Mostri in tempo reale chi è online o sta scrivendo. Il server pubblica eventi di presenza; il client visualizza un elenco con gli avatar.
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 dello stato della connessione
Mostri un banner discreto quando l'applicazione è offline o si sta riconnettendo. Lo nasconda dopo la riconnessione completa. Gli utenti tollerano molto meglio la latenza quando possono capire che cosa sta succedendo.
{!isConnected && (
<div className="connection-banner">
Reconnecting... Your changes will sync when you're back online.
</div>
)}Risoluzione dei conflitti
Le applicazioni in tempo reale devono gestire le modifiche simultanee in conflitto. Le strategie includono: last-write-wins (semplice ma con perdita di dati), vettori di versione, OT (trasformazione operativa), CRDT (Yjs, Automerge).
CRDT per la collaborazione
CRDT (Conflict-free Replicated Data Types) consente la modifica collaborativa in tempo reale senza un server centrale. Librerie: Yjs, Automerge. Utilizzati da applicazioni come Figma, Linear e quelle in stile Notion.
Prestazioni: elenchi virtualizzati
I feed in tempo reale possono diventare molto lunghi. Utilizzi elenchi virtualizzati (react-virtuoso, @tanstack/react-virtual) per visualizzare solo gli elementi visibili: memoria e CPU rimangono costanti indipendentemente dal numero totale di elementi.
Verifica rapida
Che cos'è un "aggiornamento ottimistico" in un'interfaccia utente in tempo reale?
Riepilogo: schemi per interfacce in tempo reale
Gli aggiornamenti ottimistici fanno sembrare le applicazioni istantanee; ripristini lo stato precedente in caso di errore. Utilizzi ID temporanei per gli elementi creati. Utilizzi l'accodamento locale per garantire la continuità offline. Confronti o applichi patch agli aggiornamenti del server per evitare renderizzazioni non necessarie. Limiti i flussi ad alta frequenza. Mostri la presenza (online, sta scrivendo) e i banner della connessione. Utilizzi CRDT (Yjs, Automerge) per la modifica collaborativa. Virtualizzi gli elenchi in tempo reale molto lunghi.
Domande Frequenti
La lezione «Schemi per interfacce in tempo reale» è gratuita?
Sì — il testo completo di «Schemi per interfacce in tempo reale» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Frontend Academy, passa a CoddyKit PRO. Il corso Frontend Academy include 4 lezioni in totale.
Cosa imparerò in «Schemi per interfacce in tempo reale»?
Applicare aggiornamenti ottimistici per un feedback immediato, usare code locali quando si è offline e confrontare i dati in arrivo per aggiornare nell’interfaccia solo gli elementi modificati Eserciti Frontend Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Frontend Academy?
Non è richiesta alcuna esperienza precedente. Frontend Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Schemi per interfacce in tempo reale»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Frontend Academy?
Sì. Ogni lezione Frontend Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- WebSocket API: open, message, close ed error
- Integrazione del client Socket.io
- Server-Sent Events per lo streaming unidirezionale
- Schemi per interfacce in tempo reale