La majorité des frameworks et des tutoriels partent d'une hypothèse implicite : le réseau est disponible, rapide et fiable. Sur une liaison mobile en Afrique de l'Ouest, aucune des trois n'est garantie.
Voici les décisions de conception qui font la différence entre une application utilisable et une application que les équipes contournent en reprenant le papier.
1. Distinguer « lent » de « coupé »
La plupart des applications traitent ces deux cas de la même façon : un indicateur de chargement qui tourne indéfiniment. C'est le pire comportement possible, parce que l'utilisateur ne sait pas s'il doit attendre ou recommencer.
Fixez un délai d'expiration explicite — cinq à dix secondes selon l'opération — et distinguez trois états à l'écran : en cours, échec réseau, échec serveur. Les trois appellent des actions différentes de la part de l'utilisateur.
2. Écrire localement d'abord
Quand un utilisateur valide une saisie, enregistrez-la localement avant de tenter l'envoi, puis confirmez visuellement. La synchronisation devient une tâche de fond, et une coupure ne fait plus perdre de travail.
Cette inversion change complètement le ressenti : l'application reste réactive même quand le réseau ne l'est pas. Elle impose en revanche de gérer les conflits, ce qui nous amène au point suivant.
3. Décider de la règle de conflit à l'avance
Si deux personnes modifient la même fiche hors ligne, laquelle gagne ? Ne laissez pas cette question au hasard : la réponse dépend du métier.
- Pour un stock, c'est souvent la somme des mouvements qui compte, pas la dernière valeur écrite.
- Pour une fiche client, la dernière modification datée fait généralement autorité.
- Pour une réservation, il faut un arbitrage côté serveur — deux personnes ne peuvent pas obtenir la même chambre.
Écrire cette règle noir sur blanc avant de coder évite des corrections de données pénibles six mois plus tard.
4. Rendre les envois rejouables
Sur un réseau instable, une requête peut aboutir côté serveur sans que la réponse revienne. Le client, ne voyant rien, réessaie — et crée un doublon.
La parade est simple : chaque opération d'écriture porte un identifiant unique généré par le client. Le serveur, s'il reçoit deux fois le même identifiant, applique une seule fois et renvoie le même résultat. C'est quelques lignes de code, et cela supprime toute une catégorie de bugs impossibles à reproduire.
5. Réessayer intelligemment
Un client qui réessaie immédiatement et en boucle aggrave la congestion et vide la batterie. Espacez les tentatives de façon croissante — une seconde, deux, quatre, huit — avec un plafond, et ajoutez une petite variation aléatoire pour éviter que tous les appareils ne se resynchronisent en même temps après une coupure.
6. Alléger la charge utile
Chaque octet compte quand la bande passante est rare et facturée. Deux réflexes simples : ne demandez que les champs réellement affichés, et paginez systématiquement. Une liste de clients qui renvoie l'intégralité de la base à chaque ouverture est confortable à écrire et coûteuse à utiliser.
La compression doit être active côté serveur — c'est souvent une ligne de configuration, et le gain est immédiat.
7. Dire la vérité à l'utilisateur
Une application qui affiche « Enregistré » alors que la donnée est seulement en file d'attente locale trahit la confiance dès la première perte. Affichez l'état réel : enregistré sur l'appareil, puis synchronisé. Les utilisateurs acceptent très bien un système imparfait s'ils comprennent où ils en sont.
Le test qui compte
Avant toute mise en production, faites l'exercice suivant : activez le mode avion en pleine saisie, saisissez trois enregistrements supplémentaires, puis réactivez le réseau. Tout doit se retrouver, sans doublon, sans perte, sans intervention.
Si ce test passe, votre application tiendra. S'il ne passe pas, aucune quantité de tests en conditions idéales ne vous dira ce qui vous attend sur le terrain.