Perché Offline-First?
I utenti mobili si aspettano che le app funzionino ovunque — sottoterra, in aree rurali, su voli. L'architettura offline-first assicura che l'app si degradi in modo elegante quando la connessione viene persa.
Componenti dell'Architettura
1. Database Locale
Utilizziamo Realm per lo storage locale a causa delle sue query reactive e del supporto alla risoluzione dei conflitti.
const realm = await Realm.open({ schema: [TaskSchema, UserSchema] });
// Scrivi localmente — istantaneo, senza richiesta di rete
realm.write(() => {
realm.create("Task", { id: uuid(), title: "Nuova Task", synced: false });
});
// Leggi localmente — istantaneo, senza stati di caricamento
const tasks = realm.objects("Task").filtered("synced == false");2. Motore di sincronizzazione
Un motore di sincronizzazione in background sposta le modifiche locali sul server e tira le modifiche remote quando la connessione torna.
class SyncEngine {
async syncPendingChanges() {
const pending = await this.localDb.getUnsynced();
for (const item of pending) {
try {
await this.api.push(item);
await this.localDb.markSynced(item.id);
} catch (error) {
this.queueForRetry(item);
}
}
}
}3. Risoluzione dei conflitti
| Strategy | Quando utilizzare |
|---|---|
| Last Write Wins | Dati semplici, basso rischio di conflitti |
| Merge | Modifiche complementari a campi diversi |
| Risoluzione manuale | Dati critici, conflitti di logica aziendale |
Test dell'Offline Behavior
- Test di modalità di volo su dispositivi reali
- Simulazione di throttling della rete
- Test di scenari di conflitto di sincronizzazione
- Verifica dell'integrità dei dati dopo la sincronizzazione