Aller au contenu principal
·13 min de lecture

Synchronisation offline avancée : gestion des conflits

Stratégies de sync pour apps offline-first. Conflict resolution, CRDT, eventual consistency. Guide complet pour développeurs et décideurs.

OfflineTechniqueArchitecture

Comment gérer les conflits quand deux utilisateurs modifient les mêmes données sans connexion ? C'est LA question qui fait transpirer les architectes logiciels depuis des années. Et si je vous disais qu'il n'existe pas de solution miracle, mais plutôt un arsenal de stratégies à combiner selon votre contexte ?

Chez Eurus, on a développé des apps pour des vétérinaires en zone rurale, des voyageurs sans réseau, des équipes terrain. À chaque fois, le même défi : faire en sorte que l'app reste utilisable offline tout en évitant la catastrophe quand les données se resynchronisent.

Pourquoi le offline-first n'est plus optionnel

Selon les dernières études du secteur, le marché mondial des applications mobiles devrait atteindre 613 milliards de dollars en 2025. Pourtant, près de 2,6 milliards de personnes dans le monde n'ont toujours pas accès à une connexion internet fiable. Ce chiffre n'est pas anecdotique — il représente un tiers de la population mondiale.

Mais le problème ne concerne pas que les zones rurales africaines ou les villages reculés d'Asie du Sud. Pensez à votre propre quotidien : le métro parisien, l'ascenseur de votre immeuble, cette salle de réunion au sous-sol, le tunnel sur l'A6. La connectivité est un mythe. Elle va et vient constamment.

Une étude Gartner de 2024 révélait que 78% des utilisateurs abandonnent une application qui ne fonctionne pas correctement en cas de connexion instable. Dit autrement : si votre app plante dès que le réseau faiblit, vous perdez 8 utilisateurs sur 10.

Sur Getaway, notre app de voyage développée en Flutter, on a vécu ça de plein fouet. Le plus gros challenge ? Gérer les photos offline quand les voyageurs sont dans des zones sans réseau. Un utilisateur en trek au Népal qui prend 200 photos de paysages, c'est 2 Go de données à synchroniser intelligemment. Si on avait fait du "online-first" classique, l'app aurait été inutilisable.

Les trois piliers de la synchronisation offline

Avant de plonger dans les algorithmes, posons les bases. Une architecture offline-first repose sur trois composants fondamentaux.

Le stockage local

Votre app doit pouvoir fonctionner comme si le serveur n'existait pas. Ça implique une base de données locale robuste. SQLite reste le standard pour React Native et Flutter. Realm offre des performances supérieures pour les cas complexes. Pour le web, IndexedDB fait le job, même si l'API est franchement pénible à utiliser sans wrapper.

Le choix dépend de votre stack et de vos volumes. Sur DrMilou, notre app vétérinaire, on stocke localement des milliers de dossiers animaux avec historiques médicaux complets. SQLite suffit largement. Mais pour une app collaborative temps réel type Notion ou Figma, vous aurez besoin de structures plus sophistiquées.

La file d'attente des mutations

Chaque action utilisateur offline doit être capturée et mise en queue. L'utilisateur crée un rendez-vous ? La mutation est stockée localement avec un timestamp. Il modifie une fiche patient ? Pareil. Il supprime un document ? Encore pareil.

Cette queue devient la source de vérité pour tout ce qui s'est passé pendant la déconnexion. Quand le réseau revient, on rejoue les mutations dans l'ordre.

Attention au piège classique : ne stockez jamais juste le "résultat final". Stockez les opérations individuelles. La différence est cruciale pour la résolution de conflits.

Le moteur de synchronisation

C'est le cerveau du système. Il détecte la connectivité, décide quand synchroniser, gère les conflits, et maintient la cohérence entre local et distant.

Selon une analyse Stack Overflow de 2025, la synchronisation de données figure parmi les trois défis techniques les plus complexes mentionnés par les développeurs mobile, aux côtés de la gestion de la mémoire et de la sécurité.

La vraie difficulté : les conflits de données

Imaginons un scénario simple. Alice et Bob travaillent sur le même document. Alice est dans le métro, Bob dans un avion. Les deux modifient le titre du document au même moment, sans savoir ce que l'autre fait.

Alice écrit : "Rapport Q1 2026 - Version finale" Bob écrit : "Rapport Q1 2026 - À valider par le board"

Qui gagne ? Et surtout, comment éviter de perdre le travail de l'un ou l'autre ?

Stratégie 1 : Last Write Wins (LWW)

La plus simple et la plus brutale. Le dernier à synchroniser écrase les autres. Si Bob se reconnecte après Alice, sa version l'emporte.

Avantages : trivial à implémenter, prévisible. Inconvénients : vous pouvez perdre des données. Définitivement.

Chez Eurus, on évite LWW sauf pour des données non critiques comme les préférences utilisateur ou les paramètres d'affichage. Pour tout le reste, c'est trop risqué.

Stratégie 2 : First Write Wins

L'inverse. Le premier à avoir fait la modification gagne, même s'il synchronise après.

En pratique, c'est rarement utilisé seul car ça crée de la confusion. L'utilisateur voit sa modification locale, se reconnecte, et paf — elle disparaît au profit d'une version antérieure qu'il n'a jamais vue.

Stratégie 3 : Merge automatique

Plus sophistiqué. On tente de fusionner les modifications intelligemment. Si Alice a modifié le titre et Bob a modifié le contenu, on garde les deux changements.

Le problème survient quand les modifications portent sur le même champ. Là, il faut des règles métier spécifiques. Sur DrMilou, par exemple, si deux vétérinaires modifient le poids d'un animal simultanément, on garde la valeur la plus récente (LWW sur ce champ précis) mais on conserve un historique des deux mesures. Le contexte médical l'exige.

Stratégie 4 : Résolution manuelle

Parfois, la machine ne peut pas décider. On présente les deux versions à l'utilisateur et on lui demande de choisir. C'est ce que fait Git avec ses merge conflicts.

Cette approche est honnête mais coûteuse en UX. L'utilisateur lambda ne veut pas gérer des conflits de données. Il veut que ça marche.

Une enquête Forrester de 2024 indiquait que 67% des utilisateurs professionnels préfèrent une résolution automatique "acceptable" plutôt qu'une résolution manuelle "parfaite". La friction tue l'adoption.

Les CRDT : la révolution silencieuse

Les Conflict-free Replicated Data Types représentent l'état de l'art en matière de synchronisation distribuée. L'idée géniale : concevoir des structures de données qui ne peuvent pas entrer en conflit par construction.

Comment ça marche ?

Un CRDT garantit que si plusieurs réplicas reçoivent les mêmes opérations (dans n'importe quel ordre), ils convergent vers le même état final. Mathématiquement prouvé. Pas de conflits possibles.

Prenons un exemple concret : un compteur CRDT. Plutôt que de stocker une valeur unique, on stocke un vecteur d'incréments par nœud.

Nœud A : +3
Nœud B : +5  
Nœud C : +2
Total : 10

Peu importe l'ordre de synchronisation, le total sera toujours 10. Pas de conflit.

Les types de CRDT les plus utiles

G-Counter (Grow-only Counter) : compteur qui ne fait qu'augmenter. Parfait pour les likes, les vues, les clics.

PN-Counter : compteur qui peut augmenter et diminuer. Utile pour les stocks, les quotas.

LWW-Register : un registre simple avec Last Write Wins intégré proprement. Chaque valeur porte son timestamp.

OR-Set (Observed-Remove Set) : un ensemble où l'ajout et la suppression fonctionnent sans conflit. Si j'ajoute "pomme" et tu supprimes "pomme" simultanément, le résultat dépend de qui a observé l'autre en dernier. Mais c'est déterministe.

RGA (Replicated Growable Array) : pour le texte collaboratif. Chaque caractère a un ID unique. Les insertions et suppressions sont des opérations, pas des états.

CRDT en production : retour d'expérience

Figma utilise des CRDT pour son canvas collaboratif. Notion s'appuie sur une variante pour ses blocs éditables. Linear gère ses issues avec des structures inspirées des CRDT.

Comme le souligne Martin Kleppmann, chercheur à Cambridge et co-auteur de "Designing Data-Intensive Applications" : "Les CRDT permettent une collaboration sans coordination centrale, ce qui élimine les goulots d'étranglement de performance et de disponibilité."

Sur Youdy, notre app sociale, on a exploré les CRDT pour le système de messagerie. La conclusion ? Puissant mais complexe. Pour une équipe de 3-4 devs, implémenter des CRDT from scratch est un investissement majeur. On a finalement opté pour une bibliothèque existante (Yjs) adaptée à nos besoins.

Eventual Consistency : accepter l'incertitude

Le modèle de cohérence éventuelle est le compromis réaliste du monde distribué. Plutôt que de garantir que tous les nœuds voient la même donnée au même instant (cohérence forte), on garantit qu'ils convergeront vers le même état... à terme.

Le théorème CAP en pratique

Vous connaissez probablement le théorème CAP : dans un système distribué, vous ne pouvez avoir que deux propriétés parmi Consistency (cohérence), Availability (disponibilité) et Partition tolerance (tolérance au partitionnement).

Une app offline-first choisit nécessairement AP. On tolère les partitions réseau (l'utilisateur est déconnecté) et on reste disponible (l'app fonctionne). La cohérence devient "éventuelle".

Ce n'est pas un défaut. C'est un choix architectural délibéré. Amazon, Netflix, Twitter — tous fonctionnent sur des modèles de cohérence éventuelle. Ça scale.

Concevoir pour l'incertitude

En pratique, eventual consistency implique de repenser votre UX. L'utilisateur doit comprendre intuitivement l'état de ses données.

Quelques patterns éprouvés :

Indicateurs de sync : un petit nuage avec une flèche, une pastille orange, un texte "En attente de synchronisation". Soyez explicites.

Optimistic UI : affichez immédiatement le résultat de l'action utilisateur, avant même la confirmation serveur. Si ça échoue, revenez en arrière avec un message clair.

Timestamps visibles : "Modifié il y a 5 minutes • Synchronisé" rassure l'utilisateur sur la fraîcheur des données.

Mode dégradé explicite : quand certaines fonctionnalités nécessitent une connexion, désactivez-les proprement avec une explication.

Sur Getaway, on affiche un compteur de "X éléments en attente de sync" quand l'utilisateur est offline. Dès que le réseau revient, le compteur descend. C'est satisfaisant visuellement et ça donne confiance.

Architecture technique : notre stack recommandée

Après plusieurs projets offline-first chez Eurus, voici ce qui fonctionne.

Pour React Native

WatermelonDB : base de données optimisée pour React Native avec sync intégrée. Lazy loading, observables, performances excellentes même avec 100k+ enregistrements.

MMKV : stockage clé-valeur ultra-rapide pour les données simples (tokens, préférences, cache).

NetInfo : détection de connectivité fiable.

Pour Flutter

Drift (ex-Moor) : ORM SQLite avec API réactive. Type-safe, migrations intégrées.

Hive : NoSQL local rapide pour les structures simples.

Connectivity Plus : équivalent de NetInfo pour Flutter.

Pour le web (PWA)

IndexedDB + Dexie.js : Dexie simplifie énormément l'API horrible d'IndexedDB.

Service Workers : indispensables pour le cache et le fonctionnement offline.

Workbox : toolkit Google pour les stratégies de cache.

Backend : la sync côté serveur

Côté serveur, vous avez besoin d'endpoints de sync intelligents. Le pattern classique :

  1. Le client envoie son "last sync timestamp"
  2. Le serveur renvoie tous les changements depuis ce timestamp
  3. Le client applique les changements et met à jour son timestamp

Pour les conflits, implémentez la détection côté serveur. Renvoyez un code spécifique (409 Conflict) avec les données conflictuelles. Le client décide de la stratégie de résolution.

Les pièges à éviter

Trois ans d'expérience offline-first chez Eurus, voici nos plus belles erreurs.

Le piège du timestamp naïf

Un bug de timezone sur Youdy a fait que les utilisateurs au Canada recevaient leurs rappels à 3h du mat. Leçon apprise : toujours stocker en UTC. Toujours. Les timezones sont un cauchemar, ne laissez jamais le device local décider de l'heure.

Pour la sync, utilisez des timestamps serveur ou des compteurs logiques (vector clocks). Les horloges des devices sont souvent désynchronisées.

Le piège du stockage illimité

Les devices ont des limites. iOS peut purger le cache de votre app sans prévenir si l'espace disque est faible. Android a des quotas pour IndexedDB dans les PWA.

Implémentez une politique de rétention. Gardez les données récentes en priorité. Proposez un bouton "Libérer de l'espace" dans les paramètres.

Le piège de la migration

Votre schéma de données va évoluer. Que se passe-t-il quand un utilisateur avec des données offline v1 met à jour vers l'app v2 avec un nouveau schéma ?

Planifiez vos migrations dès le début. Versionnez votre schéma local. Testez les migrations sur des données réelles, pas juste sur des bases vides.

Le piège de la suppression

Supprimer une donnée offline est compliqué. Si vous supprimez localement puis synchronisez, le serveur ne sait pas que l'enregistrement existait. Il pourrait le recréer lors du prochain sync si quelqu'un d'autre l'a modifié entre-temps.

Solution : les soft deletes avec tombstones. Marquez comme supprimé plutôt que de supprimer physiquement. Synchronisez la suppression. Purgez les tombstones après un délai de rétention.

Quand NE PAS faire du offline-first

Soyons honnêtes : le offline-first n'est pas toujours la bonne réponse.

Données temps réel critiques : une app de trading, un système de réservation de dernière minute — la cohérence forte prime sur la disponibilité offline.

Workflow séquentiel strict : si l'étape B dépend absolument du résultat serveur de l'étape A, le offline-first complique inutilement.

MVP rapide : en phase de validation, ne vous infligez pas la complexité du offline-first. Validez votre proposition de valeur d'abord. Ajoutez le offline ensuite si les utilisateurs le demandent.

En 3 ans chez Eurus, j'ai vu des projets échouer non pas à cause du code, mais parce que personne n'avait vraiment compris le besoin métier. Ne construisez pas une Ferrari offline-first si un vélo online suffit.

Checklist avant de se lancer

Avant d'implémenter la sync offline avancée, validez ces points :

  • [ ] Avez-vous identifié les entités qui doivent fonctionner offline ?
  • [ ] Connaissez-vous vos patterns d'accès concurrents (qui modifie quoi, quand) ?
  • [ ] Avez-vous choisi une stratégie de résolution de conflits par type de donnée ?
  • [ ] Votre équipe maîtrise-t-elle les concepts de base (queues, timestamps, merge) ?
  • [ ] Avez-vous prévu du temps pour les tests (simuler le offline est non trivial) ?
  • [ ] Votre UX intègre-t-elle les états de synchronisation ?

Si vous avez coché toutes les cases, vous êtes prêts.

FAQ

Quelle est la différence entre offline-first et cache classique ?

Un cache classique stocke temporairement des données pour accélérer les accès. Le offline-first permet de créer, modifier et supprimer des données sans connexion, avec synchronisation ultérieure. C'est une différence de paradigme, pas juste de technique.

Les CRDT sont-ils adaptés à tous les cas ?

Non. Les CRDT brillent pour les données collaboratives (texte, listes, compteurs). Pour des structures complexes avec relations, ils deviennent lourds à implémenter. Évaluez le rapport coût/bénéfice.

Comment tester une app offline-first ?

Utilisez le mode avion du device, mais aussi des outils comme Charles Proxy pour simuler des connexions instables (latence, packet loss). Testez les scénarios de resync après longue déconnexion.

Quel est le surcoût de développement ?

Comptez 30 à 50% de temps supplémentaire par rapport à une app online classique. C'est significatif, mais le ROI en termes de rétention utilisateur justifie souvent l'investissement.

Firebase/Firestore gèrent-ils le offline automatiquement ?

Oui, partiellement. Firestore a un mode offline intégré avec sync automatique. Mais la gestion des conflits reste basique (LWW). Pour des besoins avancés, vous devrez quand même implémenter votre logique.


La synchronisation offline avancée n'est pas un nice-to-have en 2026. C'est une attente utilisateur. Avec les bons patterns et une architecture pensée dès le départ, vous pouvez offrir une expérience fluide quel que soit l'état du réseau.

Besoin d'aide pour concevoir votre architecture offline-first ? Chez Eurus, on accompagne les équipes produit sur ces sujets techniques complexes. Parlons de votre projet →

Besoin d'accompagnement ?

Discutons de votre projet et voyons comment Eurus peut vous aider.

Nous contacter
Prendre RDV