Offline-First — je strategie vývoje mobilních a webových aplikací, při které aplikace nejprve přistupuje k lokálnímu úložišti dat a poté se synchronizuje se serverem na pozadí. Uživatel vidí rozhraní okamžitě, i bez připojení k internetu, a data se automaticky synchronizují při obnovení spojení. Podle Google Developers, 2025, přístup Offline-First zvyšuje zapojení uživatelů o 20-40% díky stabilnímu provozu v podmínkách nestabilní sítě.
Hlavní
Offline-First — je architektonický přístup k vývoji aplikací, při kterém je lokální ukládání a zpracování dat primární a síťové požadavky jsou sekundární. Na rozdíl od tradičního přístupu Online-Only, kde aplikace odesílá požadavek na server a čeká na odpověď, aplikace Offline-First nejprve čte data z lokální mezipaměti nebo databáze, okamžitě je zobrazí uživateli a teprve poté se na pozadí synchronizuje se serverem. To zcela mění uživatelský zážitek: obrazovky se načítají v milisekundách bez ohledu na rychlost internetu.
Koncepce Offline-First získává na popularitě s růstem mobilního provozu a šířením aplikací v regionech s nestabilním internetem. Podle Google I/O 2025 se více než 60% uživatelů mobilních aplikací setkává s problémy síťového připojení alespoň jednou denně. Offline-First řeší tento problém tím, že aplikaci plně zprovozní bez přístupu k internetu. Uživatel může vytvářet, upravovat a mazat data — všechny změny se ukládají lokálně a synchronizují se při obnovení připojení.
Offline-First je třeba odlišit od jednoduchého ukládání do mezipaměti. Při ukládání do mezipaměti se data nejprve načtou ze serveru a poté se uloží lokálně jako kopie. Při Offline-First je lokální úložiště zdrojem pravdy (source of truth). Uživatel pracuje s lokálními daty a server je replika. Pokud síť není dostupná, aplikace pokračuje v plném provozu. Pokud je síť dostupná, změny se synchronizují na pozadí. Tento přístup vyžaduje složitější architekturu, ale poskytuje kvalitativně odlišný uživatelský zážitek.
Existují tři přístupy k práci s daty v aplikacích. Online-Only — aplikace nefunguje bez internetu, všechna data jsou uložena na serveru. Offline-Only — aplikace funguje zcela lokálně, chybí synchronizace se serverem. Offline-First — hybrid: lokální data jako zdroj pravdy, server jako replika pro zálohování a sdílený přístup. Každý přístup má svou oblast použití: Online-Only je vhodný pro bankovní operace, Offline-Only pro kalkulačky, Offline-First pro sociální sítě, poznámky, úkoly a messenger.
Architektura Offline-First je postavena na čtyřech klíčových principech. Lokální zdroj pravdy — všechna data se nejprve uloží do lokální databáze a teprve poté se odešlou na server. Uživatel vždy vidí aktuální data z lokálního úložiště, což zajišťuje okamžitou odezvu rozhraní. Aplikace nikdy nečeká na odpověď serveru pro zobrazení dat — to je zásadní rozdíl od tradičních REST klientů s indikátory načítání.
Synchronizace na pozadí — po lokálním uložení dat aplikace nastaví úlohu synchronizace. Pokud je síť dostupná, změny se odešlou na server okamžitě. Pokud síť není dostupná, úloha se uloží do fronty a provede se při obnovení připojení. Android WorkManager a iOS BGProcessingTask jsou standardní nástroje pro implementaci tohoto principu. Řešení konfliktů — při synchronizaci mohou vzniknout konflikty, pokud byla stejná data změněna na různých zařízeních. Strategie řešení: Last-Write-Wins, Multi-Version Concurrency Control nebo CRDT.
Adaptivní rozhraní — aplikace by měla informovat uživatele o stavu synchronizace, ale neblokovat práci v offline režimu. Ikona stavu připojení, indikátor počtu nesynchronizovaných změn a oznámení o dokončení synchronizace jsou povinné prvky UX pro aplikace Offline-First. Service Worker ve webových aplikacích a Network Manager v mobilních aplikacích sledují stav sítě a řídí odesílání dat.
Cache-First — aplikace nejprve zkontroluje mezipaměť, ale pokud data nejsou, odešle požadavek na server. To je zjednodušená verze Offline-First bez fronty synchronizace a řešení konfliktů. API-First — aplikace vždy požaduje data ze serveru, mezipaměť se používá pouze jako záložní možnost při absenci sítě. Offline-First — nejkomplexnější, ale nejspolehlivější přístup, který poskytuje plnou funkčnost bez sítě a konzistenci dat při synchronizaci.
Moderní platformy nabízejí sadu nástrojů pro vytváření aplikací Offline-First. Na Androidu je hlavním nástrojem lokálního ukládání Room — knihovna nad SQLite, která poskytuje typově bezpečné API pro práci s databází. Room umožňuje ukládat složité objekty, definovat vztahy mezi tabulkami a provádět reaktivní dotazy prostřednictvím Flow a LiveData. Pro synchronizaci se používá WorkManager s omezením NetworkType.CONNECTED.
Na iOS se pro lokální ukládání používá Core Data nebo SwiftData (nový framework od Apple). Pro synchronizaci — CloudKit nebo vlastní implementace přes URLSession s úlohami na pozadí. Firebase nabízí hotové řešení Offline-First pro obě platformy: Firebase Realtime Database a Firestore automaticky ukládají data lokálně a synchronizují je při obnovení připojení. Vývojář nemusí psát kód synchronizace a řešení konfliktů — Firebase to dělá ve výchozím nastavení s politikou Last-Write-Wins.
Pro webové aplikace je klíčovým nástrojem Service Worker, který zachycuje HTTP požadavky a může vracet odpovědi z mezipaměti (Cache API). Workbox od Google zjednodušuje implementaci Service Worker s hotovými strategiemi ukládání do mezipaměti: Cache First, Network First, Stale-While-Revalidate. IndexedDB se používá pro ukládání strukturovaných dat v prohlížeči. Knihovny jako RxDB a PouchDB poskytují plnohodnotnou databázi Offline-First s replikací na server přes CouchDB.
| Platforma | Lokální úložiště | Synchronizace |
|---|---|---|
| Android | Room, SQLite, DataStore | WorkManager + SyncAdapter |
| iOS | Core Data, SwiftData, SQLite | CloudKit, URLSession Background |
| Web (PWA) | IndexedDB, Cache API, localStorage | Service Worker + Background Sync API |
| Cross-platform | Firestore, Realm, Couchbase Lite | Firebase Sync, CouchDB Replication |
Pro jednoduché aplikace s řídkou synchronizací postačí Room + WorkManager. Pro složité systémy s mnoha uživateli a vysokými požadavky na konzistenci — Firestore s vestavěnou podporou Offline-First. Pro hybridní webové aplikace — IndexedDB + Workbox. Výběr nástrojů závisí na složitosti dat, požadavcích na konzistenci, objemu synchronizace a vývojovém týmu.
Synchronizace — je nejsložitější část architektury Offline-First. Když uživatel mění data v offline režimu a jiné zařízení provádí změny stejných dat online, při obnovení připojení vzniká konflikt. Last-Write-Wins (LWW) — nejjednodušší strategie: vítězí poslední zápis podle času. Používá se ve výchozím nastavení ve Firebase a je vhodná pro většinu aplikací, kde ztráta jedné verze dat není kritická. LWW však může vést ke ztrátě změn, pokud byl uživatel dlouho offline.
Multi-Version Concurrency Control (MVCC) — složitější přístup, při kterém se ukládají obě verze dat a uživatel je vyzván k výběru správné. Tento přístup se používá v systémech pro společné úpravy (Google Docs, Notion). Pro implementaci MVCC je třeba synchronizovat hodiny zařízení (NTP) nebo používat vektorové hodiny k určení příčinných souvislostí. CRDT (Conflict-Free Replicated Data Types) — matematický přístup, který zaručuje absenci konfliktů díky speciálním datovým strukturám, které lze sloučit bez ztráty informací. CRDT se používá ve Figmě a SoundCloudu.
Pro mobilní aplikace se doporučuje začít s LWW a přidávat složitější strategie podle potřeby. Algoritmus synchronizace obvykle vypadá takto: aplikace ukládá časové razítko poslední synchronizace pro každý záznam. Při obnovení připojení se odešle pole změn s časovým razítkem. Server vrátí pole změn, které nastaly na serveru po uvedeném časovém razítku. Pro každé konfliktní pole se použije zvolená strategie. Po dokončení synchronizace se časové razítko aktualizuje.
V architektuře Offline-First všechny zápisové operace (CREATE, UPDATE, DELETE) nejprve vstupují do fronty operací. Operace obsahuje typ, identifikátor záznamu, data a časové razítko. Pokud je síť dostupná, operace se provede okamžitě. Pokud není dostupná — uloží se v lokální frontě. Při obnovení sítě WorkManager nebo BackgroundTask zpracovává frontu v pořadí FIFO. Úspěšné operace se z fronty odstraní, neúspěšné — opakují se s exponenciálním zpožděním. To zaručuje, že žádná změna uživatele nebude ztracena.
Na platformě Android je implementace Offline-First postavena kolem tří klíčových komponent: Room pro lokální ukládání, WorkManager pro synchronizaci na pozadí a ConnectivityManager pro sledování stavu sítě. Room poskytuje reaktivní přístup k datům přes Flow: UI se přihlásí k odběru změn v databázi a automaticky se aktualizuje při jakýchkoli změnách. WorkManager plánuje úlohu synchronizace s omezením NetworkType.CONNECTED, aby se úloha spouštěla pouze při připojení k internetu.
Typický scénář Offline-First na Androidu: uživatel vytvoří záznam v aplikaci. Data se uloží do Room přes repozitář. Repozitář vrátí Flow s aktualizovanými daty a UI okamžitě zobrazí nový záznam. Paralelně repozitář umístí úlohu synchronizace do WorkManager. Pokud je síť dostupná, WorkManager odešle POST požadavek na server. Pokud server vrátí chybu nebo síť není dostupná, úloha se opakuje později. Uživatel vidí indikátor synchronizace (ikona cloudu se šipkou) vedle nových záznamů.
Pro reaktivitu se používá vzor Repository + Flow. Repozitář skrývá detaily synchronizace před ViewModel: ViewModel se přihlásí k odběru Flow z Room a aktualizuje UI. Repozitář volá API a ukládá výsledek do Room. UI neví, zda byla data získána z lokální databáze nebo ze serveru — pouze reaguje na změny ve Flow. To umožňuje měnit strategii synchronizace bez změny kódu UI. Room automaticky upozorňuje Flow na změny díky LiveData/Flow anotacím.
class NotesRepository(
private val localDb: NoteDao,
private val api: NotesApi,
private val syncManager: SyncManager
) {
val notes: Flow<List<Note>> = localDb.getAllNotes()
suspend fun createNote(text: String) {
val note = Note(text = text, synced = false)
localDb.insert(note)
syncManager.enqueueSync()
}
}
V Jetpack Compose se Offline-First implementuje prostřednictvím StateFlow z ViewModel do Composable funkcí. ViewModel obdrží Flow z repozitáře, transformuje jej na StateFlow pomocí stateIn() a předá jej do Compose. Když Room změní data, Flow vydá novou hodnotu, StateFlow se aktualizuje a Compose překreslí pouze změněné prvky. To poskytuje reaktivní UI s minimálním úsilím a bez ruční aktualizace seznamů po synchronizaci.
Nejčastější chyba — používání ukládání do mezipaměti místo plnohodnotné architektury Offline-First. Vývojáři přidají Room nebo Core Data, ale nadále nejprve volají API a výsledek ukládají do databáze jako kopii. Při absenci sítě aplikace zobrazí náhradní prvek nebo prázdnou obrazovku, protože data nebyla nikdy načtena. Správný přístup — vždy číst data z lokální databáze a odpovědi API používat pouze k aktualizaci této databáze. Pokud je databáze při prvním spuštění prázdná — aplikace by měla načíst data ze serveru, uložit je lokálně a poté zobrazit.
Druhá chyba — ignorování konfliktů synchronizace. Vývojáři často spoléhají na výchozí Last-Write-Wins, aniž by zohlednili scénáře, ve kterých může uživatel přijít o důležitá data. Pokud aplikace umožňuje upravovat stejné záznamy z více zařízení, je nutné implementovat alespoň základní řešení konfliktů s upozorněním uživatele. Firebase Firestore řeší tento problém automaticky, ale vlastní implementace vyžaduje pečlivé navrhování.
Třetí problém — nezohlednění stavu sítě. Aplikace musí správně zpracovávat přechod z online do offline a zpět. Pokud uživatel odeslal formulář a připojení se ztratilo, data by měla být uložena do fronty operací, nikoli ztracena. ConnectivityManager na Androidu a NWPathMonitor na iOS umožňují sledovat změny sítě v reálném čase. Aplikace by měla zobrazovat srozumitelné UI: pokud data nejsou synchronizována — ikona „čeká na synchronizaci”, pokud není síť — ikona „offline”. To řídí očekávání uživatele a snižuje počet falešných hovorů na podporu.
Architektura Offline-First může vést k problémům s pamětí, pokud lokální databáze nekontrolovaně roste. Všechna data načtená ze serveru se ukládají lokálně, a pokud není nastavena politika čištění, velikost databáze může dosáhnout stovek megabajtů. Doporučuje se nastavit TTL (time-to-live) pro data v mezipaměti, mazat staré záznamy při synchronizaci a používat stránkování pro načítání velkých seznamů. Room poskytuje agregační funkce COUNT a DELETE pro správu velikosti databáze.
Často kladené otázky
Offline-First — lokální data jsou zdrojem pravdy, aplikace plně funguje bez sítě. Cache-First — mezipaměť se používá k urychlení, ale zdrojem pravdy je server. V Offline-First může uživatel vytvářet a upravovat data bez sítě, v Cache-First — pouze prohlížet dříve načtená data. Offline-First vyžaduje složitou synchronizaci, Cache-First — ne.
Základní strategie — Last-Write-Wins (vítězí poslední zápis). Pro složitější scénáře — MVCC s rozhraním pro výběr verze uživatelem nebo CRDT (Conflict-Free Replicated Data Types), které matematicky zaručují absenci konfliktů. Volba strategie závisí na kritičnosti dat a složitosti implementace.
Kritická data, která by neměla být ztracena při odstranění aplikace nebo selhání zařízení, vyžadují ukládání na server. Autorizační tokeny, platební údaje, historie objednávek — musí být duplikovány na serveru. Offline-First neznamená „pouze lokálně” — znamená „lokálně jako primární úložiště s replikou na serveru”.
Použijte Network Call Manager pro emulaci ztráty sítě, Throttling a Režim letadla v emulátoru. Testujte scénáře: vytváření dat bez sítě, synchronizace při obnovení, konflikty při paralelních úpravách. Android poskytuje NetworkBehavior v Robolectric, iOS — OHHTTPStubs pro simulaci síťových chyb. Integrační testy by měly kontrolovat frontu operací a řešení konfliktů.
Offline-First je nadbytečný pro aplikace, kde data musí být vždy aktuální — například burzovní kotace, online mapy nebo monitorovací systémy. Pokud uživatel nikdy nepoužívá aplikaci bez internetu a konzistence dat je kritická, architektura Online-Only s indikátory načítání je jednodušší a spolehlivější.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také