Tutoriels
Article populaire

Mobile-First en Afrique : React Native offline-first pour Keneya

Équipe Wapiki
15 Janvier 2026
8 min de lecture
React NativeMobileOffline-FirstSQLiteAfrique

Mobile-first : une nécessité en Afrique

En Afrique, 85% de l'accès internet se fait via mobile. Pour Keneya, ignorer le mobile aurait été ignorer 85% de nos utilisateurs.

Mais le mobile en Afrique a des contraintes spécifiques :

  • Connexion 3G instable
  • Coupures réseau fréquentes
  • Coût élevé de la data
  • Téléphones entrée de gamme
  • Notre approche offline-first

    L'application Keneya Mobile fonctionne même sans connexion. Les données sont synchronisées dès que le réseau revient.

    Architecture de données

    typescript
    // db/schema.ts
    import { create } from 'react-native-sqlite-storage'
    
    const db = await create({
      name: 'keneya.db',
      location: 'default'
    })
    
    // Tables principales
    await db.executeSql(`
      CREATE TABLE IF NOT EXISTS consultations (
        id TEXT PRIMARY KEY,
        patient_id TEXT,
        doctor_id TEXT,
        date TEXT,
        status TEXT,
        synced INTEGER DEFAULT 0
      )
    `)
    
    await db.executeSql(`
      CREATE TABLE IF NOT EXISTS medical_records (
        id TEXT PRIMARY KEY,
        patient_id TEXT,
        content TEXT,
        updated_at TEXT,
        synced INTEGER DEFAULT 0
      )
    `)

    Synchronisation intelligente

    typescript
    // sync/sync-manager.ts
    class SyncManager {
      async syncAll() {
        if (!await this.hasConnection()) {
          console.log('Pas de connexion, sync reportée')
          return
        }
    
        // 1. Upload des données locales non synchronisées
        await this.uploadPendingData()
    
        // 2. Download des nouvelles données du serveur
        await this.downloadServerData()
    
        // 3. Résoudre les conflits
        await this.resolveConflicts()
      }
    
      async uploadPendingData() {
        const pending = await db.executeSql(
          'SELECT * FROM consultations WHERE synced = 0'
        )
    
        for (const record of pending) {
          try {
            await api.post('/consultations', record)
            await db.executeSql(
              'UPDATE consultations SET synced = 1 WHERE id = ?',
              [record.id]
            )
          } catch (error) {
            console.error('Sync failed:', error)
          }
        }
      }
    }

    Optimisation de la taille de l'app

    Pour les téléphones d'entrée de gamme, chaque MB compte :

    1. Hérmes au lieu de JSC

    json
    // android/app/build.gradle
    project.ext.react = [
      enableHermes: true
    ]

    Résultat : APK réduit de 35MB à 22MB

    2. Images optimisées

  • Utilisation de **WebP** au lieu de PNG/JPG
  • Lazy loading des images
  • Cache local des avatars
  • 3. Code splitting

    typescript
    // Lazy loading des écrans
    const ConsultationScreen = lazy(() => import('./screens/Consultation'))
    const MedicalRecordScreen = lazy(() => import('./screens/MedicalRecord'))

    Gestion de la consommation data

    typescript
    // Sync uniquement en WiFi (option utilisateur)
    const settings = await AsyncStorage.getItem('sync_settings')
    
    if (settings.wifiOnly && !isWifiConnected()) {
      showNotification('Sync en attente de WiFi')
      return
    }
    
    // Compression des images avant upload
    const compressed = await ImageCompressor.compress(photo, {
      quality: 0.7,
      maxWidth: 1024
    })

    Résultats concrets

  • 📱 **APK size** : 22MB (vs 35MB initialement)
  • ⚡ **Fonctionne offline** : 100% des fonctionnalités de base
  • 📊 **Sync success rate** : 98%
  • 💾 **Économie data** : -40% avec compression
  • Conclusion

    En Afrique, mobile-first n'est pas un choix, c'est une obligation. Et offline-first est la seule approche viable pour garantir une expérience utilisateur fluide.


    *Vous développez une app mobile pour l'Afrique ? [Parlons stratégie](/contact).*

    Cet article vous a plu ?

    Partagez-le avec votre réseau !