5 min

PWA vs Flutter vs natif : différences entre SwiftUI et Compose expliquées

Comparez PWA, Flutter et natif (SwiftUI/Jetpack Compose) : performance, UX, hors‑ligne, APIs matérielles, distribution et adéquation à l'équipe — plus comment choisir.

PWA vs Flutter vs natif : différences entre SwiftUI et Compose expliquées

Ce que vous choisissez vraiment

Choisir entre une PWA, Flutter et le “natif” n'est pas seulement choisir un langage—c'est choisir un modèle de livraison produit.

Une PWA est un site web avec des capacités proches d'une application (installable, mise en cache pour le hors-ligne, notifications push dans certains environnements). Votre runtime principal est le navigateur, et la distribution se fait surtout via des liens.

Flutter est un toolkit UI multiplateforme qui s'expédie comme une application. Vous embarquez votre moteur de rendu et votre couche UI, visant un comportement cohérent sur iOS et Android tout en appelant les APIs de la plateforme quand nécessaire.

« Natif » aujourd'hui signifie généralement les SDKs de plateforme (iOS SDK d'Apple, Android SDK) plus des frameworks UI déclaratifs modernes : SwiftUI sur iOS et Jetpack Compose sur Android. On n'écrit plus l'UI "native à l'ancienne"—on écrit de l'UI déclarative native qui s'intègre profondément aux conventions de la plateforme, à l'accessibilité et aux composants système.

La décision que nous prenons

Cet article compare PWA vs Flutter vs natif (SwiftUI/Compose) comme choix de bout en bout : caractéristiques de performance, fidélité UX, capacités et charge opérationnelle—pas seulement « quel est le plus agréable à coder ».

Les critères utilisés

Nous évaluerons chaque option selon un ensemble de questions cohérent :

  • Performance & réactivité (temps de démarrage, animations, défilement)
  • Fidélité UI (look-and-feel plateforme, accessibilité, comportements d'entrée)
  • Hors-ligne, push et travail en arrière-plan
  • APIs matérielles (appareil photo, Bluetooth, biométrie, paiements…)
  • Distribution & mises à jour (stores vs web, cycles de revue, monétisation)
  • Productivité & maintenabilité développeur
  • Présence web (SEO, liens profonds, partage)
  • Sécurité, vie privée et conformité
  • Coût, time-to-market et risque

Une attente à poser

Il n'existe pas de « meilleur universel ». La bonne réponse dépend de vos utilisateurs, de votre jeu de fonctionnalités, des compétences de votre équipe et de votre manière d'expédier et d'itérer.

Principes d'architecture : comment chaque technologie fonctionne

Le choix entre PWA, Flutter et natif (SwiftUI/Jetpack Compose) est en grande partie un choix de runtime et de pipeline de rendu : où votre code s'exécute, qui dessine les pixels et comment vous accédez aux capacités de l'appareil.

PWA : moteur de navigateur + Web APIs + Service Worker

Une PWA s'exécute dans le moteur du navigateur (WebKit sur iOS, moteurs basés sur Chromium sur la plupart des navigateurs Android). Votre code est du HTML/CSS/JavaScript exécuté par le moteur JS, et l'UI est produite par le système de mise en page et rendu du navigateur.

Éléments architecturaux clés :

  • Web APIs (stockage, réseau, capteurs quand disponibles) fournissent des capacités avec permission et sandbox gérées par le navigateur.
  • Service Worker est un script d'arrière-plan qui peut intercepter les requêtes, mettre en cache les réponses et permettre le hors-ligne. Il est piloté par des événements et peut être mis en pause entre les événements, ce qui limite le travail de fond long.

En pratique, vous construisez sur un runtime web standardisé mais avec des variations et des contraintes entre navigateurs—surtout sur iOS.

Flutter : runtime Dart + rendu Skia + platform channels

Flutter embarque son propre framework UI et pipeline de rendu. Votre code Dart s'exécute dans le moteur Flutter (JIT en debug, compilé AOT en release). Plutôt que de s'appuyer sur des widgets natifs, Flutter dessine tout via Skia, produisant un rendu cohérent sur les plateformes.

Quand Flutter a besoin de fonctionnalités spécifiques (caméra, paiements, capteurs), il utilise des platform channels (ou plugins) pour appeler du code natif. Cette limite est explicite : itération UI rapide en Dart, plus des ponts natifs ciblés pour l'intégration plateforme.

Natif : Swift/SwiftUI et Kotlin/Compose + toolkits UI système

Les apps natives s'exécutent directement sur le runtime de la plateforme (iOS : Swift/Obj‑C sur les frameworks Apple ; Android : Kotlin/Java sur ART). Avec SwiftUI et Jetpack Compose, vous écrivez une UI déclarative, mais le rendu est assuré par les toolkits système.

Cela signifie que les apps natives héritent du comportement plateforme « par défaut » : accessibilité, rendu du texte, entrée, navigation et composants système—sans couche de pont supplémentaire.

Performance et réactivité

La performance, ce n'est pas que des benchmarks—c'est ce que ressent l'utilisateur : rapidité d'ouverture, fluidité du défilement et impression que les animations répondent immédiatement. Le même produit peut paraître premium ou lent selon la stack.

Performance perçue : démarrage, scroll et animations

Natif (SwiftUI/Jetpack Compose) gagne généralement sur le cold start et la latence entrée→rendu car il s'exécute sur le runtime plateforme, profite de l'ordonnancement système et évite des couches d'abstraction supplémentaires. Les interactions à haute fréquence restent prévisibles.

Flutter peut être très fluide une fois lancé, car il dessine via son moteur. Cette cohérence permet d'obtenir des animations à 60/120fps quand l'UI est bien optimisée. Le démarrage peut être un peu plus lourd que le natif, et les animations très lourdes peuvent nécessiter du tuning (caching, éviter l'overdraw).

PWA s'améliore continuellement, mais reste limitée par le navigateur : exécution JS, recalculs DOM/layout et coût du rendu de pages complexes. Un défilement fluide est possible, mais de grandes structures imbriquées, des reflows fréquents et des scripts tiers lourds ajoutent rapidement du jank.

Travail en arrière-plan et contraintes

Les capacités d'arrière-plan influent indirectement sur la réactivité : pouvez‑vous pré‑charger, synchroniser silencieusement ou garder l'état à jour ?

  • PWA iOS : limitations fortes—le sync en arrière-plan et les tâches longues sont restreintes, donc l'app peut sembler « périmée » tant qu'on ne l'ouvre pas.
  • Flutter & natif : peuvent utiliser les APIs de fond de la plateforme (même si le système impose des limites), permettant un pré‑chargement plus intelligent et des états « ready » plus rapides.

Compromis de rendu : DOM vs canvas Flutter vs widgets natifs

  • PWA : moteur de layout web + DOM/CSS. Excellent pour le contenu textuel, mais une UI complexe peut provoquer des thrashs de layout.
  • Flutter : rendu basé sur Skia. Visuels cohérents, mais vous payez le coût de tout dessiner vous‑même.
  • Natif : composants système et compositeur. Souvent le chemin le plus efficace pour une UI standard de plateforme.

Quand les différences comptent

Les écarts se voient surtout sur des feeds infinis, cartes avec overlays, chat / mises à jour en temps réel, grilles d'images lourdes et UIs riches en gestes. Pour des formulaires simples, du contenu ou des flux CRUD, une PWA ou une app Flutter bien conçue peut être assez rapide—le goulot est souvent le réseau et la gestion des données plutôt que le rendu.

Expérience utilisateur et fidélité UI

La fidélité UI concerne moins la beauté visuelle que le comportement attendu : navigation, gestes, rendu du texte, haptiques et accessibilité. C'est là que PWA, Flutter et natif diffèrent le plus.

Conventions plateforme : navigation, gestes et texte

Natif gagne souvent sur le ressenti « ça sonne juste ». Glisser pour retourner, barres de navigation système, sélection de texte, physique du scrolling et comportements d'entrée suivent les mises à jour OS presque automatiquement.

Flutter peut reproduire beaucoup de conventions, mais il faut choisir : expérience cross‑platform unique ou adaptations par plateforme. En pratique, il faudra parfois du code distinct pour la navigation, l'évitement du clavier et la typographie.

PWA progresse, mais les contraintes du navigateur peuvent se traduire par des transitions non natives, une intégration de gestes limitée et des différences de rendu de police ou de comportement d'entrée.

Design systems : Material, Cupertino et branding

Compose s'intègre naturellement à Material 3 ; SwiftUI s'aligne sur les patterns iOS. Flutter propose Material et Cupertino, plus un contrôle total pour un branding personnalisé. Le coût est la maintenance : une personnalisation lourde complexifie les montées de version et l'alignement plateforme.

Les PWAs peuvent implémenter n'importe quel système de design, mais vous recréez des composants que la plateforme fournit et que les utilisateurs reconnaissent.

UI complexe : animations, transitions et gestion d'entrée

Flutter excelle pour des UIs personnalisées et des animations fluides et cohérentes sur les appareils. Le natif est tout aussi puissant, mais les transitions avancées demandent parfois une connaissance plus profonde de la plateforme.

Les PWAs peuvent réaliser des mouvements impressionnants, mais les interactions complexes atteignent vite les limites de performance des appareils bas de gamme.

Accessibilité : lecteurs d'écran, typographie dynamique, ordre du focus

Les stacks natifs offrent les primitives d'accessibilité les plus fiables : rôles sémantiques, gestion du focus, Dynamic Type/augmentation de police et lecteurs d'écran système.

Flutter supporte bien l'accessibilité, mais il faut être rigoureux sur les sémantiques, l'ordre du focus et l'échelle du texte.

Les PWAs s'appuient sur le support web de l'accessibilité, qui peut être excellent—mais certains comportements de lecteurs d'écran mobiles et réglages système ne se traduisent pas parfaitement via le navigateur.

Hors‑ligne, push et fonctionnalités en arrière‑plan

Commencez avec des données solides
Mettez en place un backend Go + PostgreSQL pour toute application PWA, Flutter ou native.

Le hors‑ligne est souvent le premier endroit où le « cross‑platform » cesse d'être identique. PWAs, Flutter et natif peuvent tous donner une impression offline‑first—mais différemment.

Offline‑first : cache, sync et conflits

PWA : le Service Worker et une stratégie de cache (app shell + runtime caching) sont la base. Idéal pour les flux majoritairement en lecture (contenu, formulaires, checklists). Les écritures nécessitent une file d'attente locale, une logique de retry et une résolution de conflits (timestamps, vecteurs de version ou règles côté serveur). Le plus : règles de cache explicites ; le moins : quotas de stockage et exécution en arrière‑plan variables.

Flutter : vous contrôlez toute la pile cliente. Pattern typique : base locale + couche de sync (ex. repository avec table d'« outbox »). La résolution de conflits est équivalente au natif, et vous évitez bien des surprises liées à l'éviction de cache du navigateur.

Natif : meilleur choix quand les besoins offline sont stricts (gros jeux de données, durabilité garantie, règles complexes de conflit, sync en arrière‑plan). Vous avez aussi un contrôle plus fin sur les conditions réseau et l'ordonnancement OS.

Options de stockage et limites

PWA : IndexedDB est l'outil principal (données structurées, capacité correcte mais non garantie). Le stockage peut être effacé sous pression et le quota varie selon navigateur/appareil.

Flutter : SQLite, Realm via plugins, et stockage de fichiers sont courants ; la persistance est plus prévisible que dans un sandbox navigateur.

Natif : bases de données first‑class (Core Data/SQLite sur iOS, Room/SQLite sur Android) avec persistance et outils les plus fiables.

Push et tâches d'arrière‑plan

Push PWA : supporté sur Android/Chromium ; sur iOS le support existe mais est plus contraint et l'expérience utilisateur moins consistante.

Flutter/natif push : APNs et FCM offrent une livraison plus interchangeable, des contrôles riches, et une intégration plus profonde (canaux, alertes critiques où permises, deep links).

Sync périodique / tâches planifiées : les PWAs ont des options limitées et dépendantes du navigateur. Flutter peut utiliser les schedulers plateforme via des plugins, mais il faut respecter les limites iOS. Le natif offre le plus large éventail (BackgroundTasks iOS, WorkManager Android) et les meilleures chances d'exécution réelle.

FAQ

Quelle est la règle simple pour choisir PWA vs Flutter vs natif ?

Choisissez une PWA si les liens, le SEO et les déploiements instantanés sont prioritaires et que vous pouvez vivre avec les contraintes du navigateur (surtout sur iOS).

Choisissez Flutter si vous voulez une base de code unique iOS/Android avec un contrôle fort sur l'UI et que vous acceptez de gérer quelques ponts vers la plateforme.

Choisissez natif (SwiftUI/Compose) si vous avez besoin du meilleur niveau de finition plateforme, de performances prévisibles et des capacités profondes du système (background, APIs matérielles).

Que choisissez-vous réellement sous le capot (runtime et rendu) ?

C'est principalement une décision de runtime + rendu :

  • PWA : s'exécute dans le navigateur ; l'UI est du DOM/CSS ; les capacités viennent des Web APIs et du Service Worker.
  • Flutter : s'exécute dans le moteur Flutter ; l'UI est dessinée par Skia ; les fonctionnalités matérielles via des plugins/plateform channels.
  • Natif : s'exécute sur les runtimes iOS/Android ; l'UI utilise SwiftUI/Compose et les composants système.
Quelle option donne généralement la sensation de la plus grande rapidité pour les utilisateurs (démarrage, défilement, animations) ?

En général, le natif l'emporte pour le démarrage à froid et la latence entrée→rendu puisqu'il utilise la pile système.

Flutter peut être extrêmement fluide une fois lancé, mais le cold start peut être un peu plus lourd et certaines animations graphiques demandent un ajustement.

PWA dépend fortement du coût JavaScript + DOM/layout ; les mises en page complexes et scripts tiers provoquent le plus souvent du jank.

Quelle approche offre l'UX la plus “natif” et respecte le mieux les conventions de plateforme ?

Le natif est en règle générale le meilleur pour le ressenti “natif” : gestes de retour, sélection de texte, physique du scroll, gestion du clavier et navigation système.

Flutter peut atteindre ce résultat, mais nécessite souvent des ajustements par plateforme.

PWA peut être très belle visuellement, mais certaines transitions et comportements d'entrée restent limités ou variables selon le navigateur.

Comment les patterns offline-first diffèrent-ils entre PWA, Flutter et natif ?

Les trois peuvent être offline-first, mais la fiabilité varie :

  • PWA : le Service Worker et le cache permettent un excellent offline en lecture, mais l'exécution en arrière-plan et la conservation du stockage peuvent interrompre la synchronisation.
  • Flutter : pattern courant : base locale + « outbox » pour les mutations ; le cycle de vie et la persistance sont plus prévisibles que dans un navigateur.
  • Natif : le meilleur choix si les exigences offline sont strictes (grands volumes de données, durabilité, règles complexes de résolution de conflits, synchronisation en arrière-plan).
À quel point les notifications push et les tâches en arrière-plan sont-elles fiables selon les trois approches ?

Pratique :

  • Push PWA : solide sur Android/Chromium ; sur iOS c'est plus contraint et peut être source de frictions pour l'utilisateur.
  • Push Flutter/natif : utilisent FCM (Android) et APNs (iOS) avec un contrôle et une intégration plus riches.

Pour le travail périodique en arrière-plan, natif (et Flutter via les APIs de plateforme) offre de meilleures options d'ordonnancement que les PWAs.

Quel choix est préférable quand l'intégration matérielle (BLE/NFC/biométrie) est au cœur du produit ?

Si vous avez besoin de Bluetooth, NFC, Wallet/Health, SDKs fournisseurs ou modes d'arrière-plan avancés, le natif est le plus sûr.

Flutter peut gérer beaucoup d'APIs via des plugins, mais prévoyez du temps pour écrire des platform channels pour les cas limites.

PWA a un support plus restreint et incohérent sur mobile—particulièrement pour les fonctionnalités matérielles pointues.

Comment la distribution et la vitesse de mise à jour se comparent-elles (stores vs web) ?

PWA se met à jour quand vous déployez—pas d'examen en store pour la plupart des changements—donc les hotfixes sont très rapides.

Flutter/natif passent par l'App Store/Play Store, ce qui ajoute signature, cycles de revue (surtout iOS) et gestion des releases. Vous pouvez mitiger avec déploiements progressifs et feature flags, mais les binaires restent soumis aux stores.

Comment la monétisation diffère-t-elle entre PWA et applications store ?

Si vous dépendez de découverte via store ou d'achats intégrés pour des biens numériques, les apps store (natif/Flutter) sont la voie la plus directe—avec les contraintes de partage de revenus et de politiques.

Les PWAs peuvent utiliser des paiements web (ex. Stripe) quand c'est autorisé, ce qui améliore la flexibilité et la marge, mais peut être limité par les règles de plateforme et la confiance des utilisateurs.

Quels sont les coûts et risques cachés les plus courants lors du choix d'une approche ?

Les coûts cachés proviennent souvent de la matrice de tests :

  • PWA : les différences de navigateurs (notamment iOS Safari/WebKit) peuvent dominer le temps QA.
  • Flutter : moins de variance UI, mais les plugins et platform channels demandent des tests sur appareils réels.
  • Natif : deux stacks à construire et tester, mais le comportement est généralement plus prévisible sur chaque plateforme.

Étape pratique : listez vos fonctionnalités indispensables (push, sync background, BLE, paiements) et validez-les sur vos appareils cibles avant de vous engager.

Related posts