React Native pour le développement de vos applications mobiles cross-platform
29 septembre 2022
React Native est un framework Open Source pour application mobile, soutenu par Facebook, et qui s’appuie sur le très riche écosystème de React.js. Utilisé par des acteurs majeurs du marché de l’application comme Airbnb, SoundCloud ou encore Instagram, ce framework est largement plébiscité et reconnu pour sa robustesse.
Sommaire :
L’histoire de React Native
Tout a commencé avec React.js et la volonté d’apporter au mobile les techniques du web moderne de l’époque. Remontons donc en arrière dans le temps, jusqu’en 2013, dans les locaux de Facebook, société créatrice de la bibliothèque, qui vient de publier sa première version publique sous licence Apache 2.0.
Dès lors, React.js devient une référence au sein de la firme pour leurs développements front-end, ainsi que le socle de référence pour leur département R&D. Ceci donne alors naissance à plusieurs composants dans le site du réseau social, mais aussi à des frameworks bâtis au-dessus de React, comme Relay par exemple.
Bien sûr, le web n’est qu’une partie de l’histoire. Facebook propose également des applications Android et iOS qui, en 2013 sont construites sur des piles technologiques propriétaires et disjointes. Mais cela divise les équipes au sein de Facebook car l’entreprise livre à cette période une nouvelle version du site web deux fois par jour, de sorte qu’ils peuvent obtenir les résultats d’une expérience presque immédiatement. En revanche sur le mobile, il faut souvent attendre des semaines ou des mois pour obtenir les résultats d’une expérience ou d’un test A/B, car les nouvelles versions de l’application sont publiées beaucoup moins souvent.
Néanmoins, le natif reste nécessaire à cette époque pour avoir accès aux composants UI spécifiques à l’OS (comme la cartographie, les sélecteurs de date, les commutateurs ou encore les piles de navigation). De plus, la gesture est beaucoup plus sophistiquée en natif que sur le web, et le JavaScript ne permet pas de faire du multi-threading que Facebook utilise pour le décodage des images par exemple.
Un hackaton s’organise donc en interne dans la compagnie afin de combiner le meilleur du natif et du web ; c’est-à-dire l’UX des plateformes mobiles natives et l’expérience de développement du web avec React. Plusieurs solutions en découlent :
- Utiliser des WebViews dans les applications natives : cela permettrait de tirer pleinement profit de l’expérience de développement en React et du cycle d’itération rapide du web. Cependant, si le rendu est effectué à l’aide des technologies web, l’UX native est difficilement reproductible et maintenable et les performances sont dégradées.
- Faire un portage de React en code natif : cette seconde option voit le jour sous le nom de “ComponentKit”, mais pour iOS uniquement. Avec ComponentKit, l’application bénéficie de tous les avantages de React, notamment des interfaces utilisateur déclaratives et prévisibles. Elle profite également de la puissance de l’environnement natif, avec des composants spécifiques à la plateforme et une gestion sophistiquée des gestes, ainsi qu’un décodage asynchrone des images, une mesure du texte et un rendu. En outre, ComponentKit utilise la méthode “Flexbox” pour la mise en page, ce qui évite de devoir positionner et dimensionner manuellement les vues de l’application, de sorte que votre code est plus concis et plus facile à maintenir.
- Créer une librairie de scripting natif : cette solution utiliserait JavaScript pour faire appel aux API natives et donc avoir accès à toute la puissance de l’environnement natif, mais aussi à la capacité d’itération rapide et de fonctionnement sur des OS autres que iOS. Différents frameworks font déjà cela à cette époque, mais avec certains désagréments comme par exemple des blocages du thread des UI par l’exécution de JavaScript dans le cadre d’allers-retours synchrones entre l’environnement natif et l’environnement interprété.
Bien que le défi soit élevé et que les obstacles soient importants, les ingénieurs chez Facebook optent finalement pour cette dernière solution et produisent une nouvelle librairie, basée sur React.js, appelée React Native, afin de fournir des applications hybrides. En résulte quelques premières applications, notamment Facebook Groups, composée de vues construites à la fois avec du code natif et du JavaScript sous React Native, et Facebook Ads Manager entièrement bâtie avec React Native.
C’est ainsi que, en janvier 2015, une première présentation de la bibliothèque React Native est présentée en avant-première au public lors de la React.js Con. Deux mois plus tard, lors de la conférence F8, Facebook annonce la mise à disposition de la librairie React Native pour iOS en Open Source, avec la promesse d’une prise en charge rapide d’Android.
Quelques mois plus tard, en septembre 2015, la promesse de compatibilité Android est tenue et une nouvelle version est publiée, ouvrant la librairie React Native aux deux systèmes d’exploitation.
En 2016, soit un an après la présentation de React Native lors de la conférence F8, Facebook et Microsoft présentent conjointement le support de React Native pour Universal Windows Platform.
En à peine un an, l’adoption de React Native et sa communauté de développeurs se sont toutes deux développées beaucoup plus rapidement que prévu.
Plus de 650 personnes ont ajouté du code à la base de code React Native. Sur les 5 800 commits de la base de code, 30% ont été effectués par des contributeurs qui ne travaillaient pas chez Facebook. En février 2016, pour la première fois, plus de 50% des commits provenaient de contributeurs externes. Avec autant de personnes de la communauté contribuant à React Native, le repository Github a vu jusqu’à 266 nouvelles pull requests par mois (jusqu’à 10 pull requests par jour).
Cette popularité a permis au fil du temps, de faire rapidement évoluer la librairie React Native avec des fonctionnalités telles que le Hot reloading, l’accessibilité, les performances, le support d’écriture Right-to-Left, le SDK Expo, le starter-kit “Create React Native App”, le support AWS Amplify, le support de Typescript.
En 2019, Facebook annonce Hermes, un moteur JavaScript léger et optimisé pour l’exécution de React Native sur Android. Hermes améliore les performances de React Native en diminuant l’utilisation de la mémoire, en réduisant la taille des téléchargements et en réduisant le temps nécessaire à l’application pour devenir utilisable ou « temps d’interaction ».
En octobre 2021, Facebook annonce que le moteur Hermes va devenir le moteur par défaut pour React Native, annonce ensuite confirmée depuis juillet 2022 et les versions de pre-realese 0.70.0 de React Native. Ce changement s’opère afin d’améliorer les performances des applications mobiles Android et iOS en déplaçant les opérations de parsing et de compilation, du runtime vers le buildtime.
En plus d’Hermes, 2022 est aussi l’année du changement pour l’architecture React Native. La mise à jour signe la fin des Native Modules et Native Components, au profit de leurs équivalents : “TurboModule” et “Fabric Components”. Cette nouvelle architecture React Native, liée à Hermes, a pour but de rendre encore plus natives les applications mobiles React Native et d’optimiser les performances de calcul et de rendu, donnant ainsi de nouvelles perspectives, notamment au niveau des animations de composants ou de la gestion des gestes.
Toutes ces nouveautés relancent ainsi les éternels débats entre les technologies : “natif vs cross-platform”, “react native vs flutter vs .NET MAUI”, “application hybride vs PWA” … Nous avons d’ailleurs nous aussi pris la parole sur ce sujet pour contribuer au débat à travers un webinar : Application native ou cross-platform : comment faire son choix ?
Le cross-platform
Aujourd’hui, quel que soit le domaine d’expertise promu ou le marché visé, une solution mobile est devenue indispensable. Il existe différentes technologies permettant de répondre aux attentes des utilisateurs et d’atteindre les objectifs marketing. Les technologies cross-platform gagnent de plus en plus de terrain pour le développement des applications mobiles, et prennent ainsi une place de plus en plus importante face aux technologies de développement d’applications natives.
Ces technologies cross-platform offrent l’avantage d’une meilleure productivité : la durée et les coûts de développement et de maintenance sont considérablement réduits, puisqu’au lieu d’avoir différentes copies du même logiciel pour différents systèmes d’exploitation, le développement d’applications crossplatform crée un programme unique qui fonctionne sur plusieurs plateformes. En utilisant une base de code unique, transparente et compatible avec tous les systèmes d’exploitation, les développeurs peuvent commencer à créer des applications mobiles.
Le développement multiplateforme présente de nombreux avantages, mais nécessite néanmoins de prendre quelques précautions et d’anticiper certains facteurs. Je vous propose de découvrir tout cela dans un autre article que j’ai pu rédiger, dédié au cross-platform, et de nous concentrer ici sur React Native, technologie cross-platform par excellence.
Comment fonctionne React Native ?
Les fondamentaux de React Native
La librairie React, bien connue pour créer des interfaces utilisateurs via JavaScript, sert de base à React Native. Ce dernier utilise donc les mêmes concepts que son aîné : des composants, le langage JSX, des props, un state, la possibilité d’utiliser des hooks, …
Une application React Native va donc être rendue en utilisant des vues natives, mais le code JavaScript n’est pas compilé dans le langage natif de la plateforme.
Les interfaces utilisateur en React Native utilisent des composants et suivent le principe unidirectionnel propre à React. L’application dispose donc d’un arbre de composants. La communication entre ces composants se fait par le biais de propriétés (appelées props) et de callbacks (fonction à appeler suite à un déclencheur). Ce callback est transmis à un composant enfant si un composant parent a besoin de quelque chose de sa part. De la même manière, une (ou plusieurs) propriété est transmise au composant enfant s’il a besoin de quelque chose de son parent.
React Native exploite une base de code JavaScript et celle-ci doit finir par être comprise par du code propriétaire comme Objective-C ou Swift pour iOS, et Java ou Kotlin pour Android. Nous parlons donc d’un langage du Web, interprétable, qui va devoir discuter avec un langage natif compilé.
Lorsque vous utilisez React Native, vous allez pouvoir exécuter votre code dans deux environnements :
- Dans la plupart des cas, React Native utilisera JavaScriptCore, le moteur JavaScript qui alimente Safari. JavaScriptCore est un framework qui permet d’exécuter du code JavaScript sur des appareils mobiles, par exemple. Sur les appareils iOS, ce framework est directement fourni par le système d’exploitation. Les appareils Android ne disposent pas de ce dernier, React Native l’intègre donc à l’application elle-même.
- Lorsque vous utilisez le débogage Chrome, tout le code JavaScript s’exécute dans Chrome lui-même, communiquant avec le code natif via des WebSockets. Chrome utilise le moteur JavaScript V8.
Pour rester compatible, React Native s’appuie par défaut sur le compilateur JavaScript Babel. Ce dernier va permettre la prise en charge de transformation du langage, notamment pour profiter au mieux des dernières avancées liées aux versions ECMAScript, en apportant des polyfills.
L’architecture React Native
Avant la nouvelle architecture React 18
Une application React Native est divisée en trois parties différentes : le code natif, le code JavaScript et le bridge. Ce dernier interprète le code JS pour l’exécuter sur des plateformes natives et permet une communication asynchrone entre les éléments natifs et le code JavaScript.
Plusieurs couches vont donc être impliquées :
- Le thread natif : le thread principal, également appelé thread natif, est utilisé pour le rendu de l’interface utilisateur dans les applications iOS et Android. Il gère la tâche d’affichage des éléments de l’interface utilisateur et traite les gestes des utilisateurs.
- Le thread d’exécution JavaScript : le thread JS s’occupe essentiellement de la logique métier de l’application et définit la structure ainsi que les fonctions de l’interface utilisateur. Les fonctions du thread JavaScript comprennent l’exécution du code JS dans un moteur distinct, les appels API, le traitement des événements tactiles, …
- Le thread Shadow Tree : ce thread génère des nœuds fantômes et agit comme un moteur mathématique qui utilise des algorithmes pour transformer les mises à jour de layout en données précises et les événements de l’interface utilisateur en charge utile correctement sérialisée.
- Le thread de modules natifs : lorsqu’une application doit accéder à l’API de la plateforme, le processus se déroule dans le thread du module natif.
- Les threads des modules natifs personnalisés : ces threads sont utilisés pour accélérer les performances d’une application lorsque des modules personnalisés sont utilisés. Par exemple, React Native gère les animations à l’aide d’un thread natif distinct afin que cette tâche soit déchargée du thread JS.
Au lancement d’une application, le thread natif charge l’application et spawn le thread JavaScript, qui exécute le code JS. Les événements liés au toucher, à l’appui et à l’interface utilisateur sont détectés par le thread natif, qui les transmet ensuite au thread JS via le bridge React Native.
Une fois le JavaScript chargé, le thread correspondant informe le shadow thread des informations qui doivent être rendues à l’écran. Le shadow thread détermine ensuite comment calculer les positions de la vue et utilise des méthodes pour calculer les mises en page. Après le rendu de la vue, le thread principal reçoit les paramètres de mise en page du shadow thread.
Ensuite, les événements de l’interface utilisateur sont collectés par le thread principal et envoyés au shadow thread. Les événements sont sérialisés en charges utiles et transmis au thread JS.
Enfin, le thread JavaScript examine les charges utiles et invoque les fonctions natives ou modifie l’interface utilisateur.
Ces étapes se répètent continuellement à chaque itération de la boucle d’événements de JavaScript.
Une fois que chaque boucle d’événement du thread JS est terminée, le côté natif reçoit les mises à jour par lots des vues natives ; celles-ci sont ensuite exécutées dans le thread natif. Il est à noter que les mises à jour par lots doivent être envoyées par le thread JS au thread natif avant la date limite de rendu de l’image suivante, afin de maintenir les performances de l’application. Un thread JS lent en raison d’un traitement compliqué dans la boucle d’événements JS nuit à l’interface utilisateur. La seule exception où un thread JS lent n’affecte pas les performances est dans les scénarios où les vues natives se déroulent entièrement dans le thread natif.
Pour éviter qu’un thread ne bloque l’autre, le bridge React Native permet une communication asynchrone entre les threads. De plus, les messages sont mis en lots, ou passés entre les threads de manière efficace. En outre, le bridge sérialise les communications pour empêcher le partage des données ou l’exploitation des mêmes données par deux threads.
Depuis la nouvelle architecture React 18 et Hermes
Hermes
Comme expliqué précédemment, React Native peut s’exécuter dans deux environnements :
- JavaScriptCore dans votre appareil mobile
- Le moteur Chrome V8
Bien que les deux environnements soient très similaires, cela peut provoquer certaines incohérences. De plus, les applications de plus grande taille utilisant des frameworks JavaScript connaissent souvent des problèmes de performance à mesure que les développeurs ajoutent des fonctionnalités et de la complexité. Cela fait donc un certain temps que Facebook travaille sur le fait de moins faire appel au “runtime” JavaScript pour améliorer les performances des apps, même sur les appareils grand public dont la mémoire est limitée, le stockage lent et la puissance de calcul réduite.
Une des clés principales qu’amène Hermes est donc la pré-compilation du bytecode. En général, après avoir été chargé, un moteur JavaScript analyse la source et produit du bytecode. Le début de l’exécution de JavaScript est retardé par cette étape. Hermes utilise un compilateur avancé, qui s’exécute dans le cadre du développement d’applications mobiles, pour omettre cette phase. Par conséquent, plus de temps peut être consacré à l’optimisation du bytecode, le rendant plus compact et plus efficace. Il est possible d’effectuer des optimisations sur l’ensemble du programme, comme la déduplication des fonctions et l’empaquetage des tables de chaînes.
Le bytecode est conçu pour être mappé en mémoire au moment de l’exécution et interprété sans qu’il soit nécessaire de lire avidement le fichier entier. Sur de nombreux appareils mobiles moyen et bas de gamme, les E/S de la mémoire flash introduisent une latence importante. Le chargement du bytecode à partir de la mémoire flash uniquement lorsque cela est nécessaire et l’optimisation de la taille du bytecode se traduisent par des améliorations notables du TTI (Time To Interact). De plus, les systèmes d’exploitation mobiles qui n’effectuent pas de swap, comme Android, peuvent toujours évincer ces pages en cas de contrainte mémoire, car la mémoire est mappée en lecture seule et soutenue par un fichier. Sur les appareils dotés d’une mémoire limitée, cela réduit le nombre de processus tués par l’épuisement de la mémoire.
Une autre clé majeure des performances du moteur Hermes réside dans la mise en place de son “garbage collector”. L’utilisation efficace de la mémoire est particulièrement cruciale pour les appareils mobiles. Les systèmes d’exploitation ne prennent généralement pas en charge le swapping. Les applications gourmandes en mémoire sont interrompues de force par les systèmes d’exploitation sur les appareils bas de gamme, et la mémoire est une ressource rare. Les fonctionnalités d’arrière-plan en pâtissent et de longs redémarrages sont nécessaires lorsque les applications sont interrompues.
Hermes inclut donc un garbage collector pour réduire la quantité de mémoire et d’espace en adressage virtuel que le moteur utilise.
Nouvelle architecture
La première évolution de l’architecture React Native concerne JSI.
Jusqu’à présent, React Native utilisait le Bridge dans la conception pour assurer la communication entre les threads JavaScript et natif. Les données devaient être sérialisées en JSON avant d’être envoyées à travers le bridge à tout moment. Les données devaient également être décryptées lorsqu’elles étaient reçues du côté opposé. Cela implique qu’il n’y a pas de communication entre les mondes JavaScript et Natifs.
Toutefois, dans la nouvelle architecture, le bridge est remplacé par un module appelé JavaScript Interface (JSI), qui est une couche légère et polyvalente, écrite en C++, pouvant être utilisée par le moteur JavaScript pour invoquer directement des méthodes dans le domaine natif.
JSI est donc découplée du moteur, ce qui signifie que la nouvelle architecture permet l’utilisation d’autres moteurs JavaScript comme Chakra, v8, Hermes…
Un autre évolution principale de l’architecture est le système de rendu “Fabric”, qui remplace le Manager UI.
Auparavant, React exécutait le code et créait un “ReactElementTree” en JavaScript. Sur la base de cet arbre, le Renderer créait un “ReactShadowTree” en C++. Cet arbre était utilisé par le moteur de mise en page pour calculer les positions des éléments de l’interface utilisateur pour l’écran hôte. Une fois que les résultats du calcul de la mise en page étaient disponibles, le shadow tree était transformé en “HostViewTree”, qui comprenait des éléments natifs.
Selon la documentation Facebook : « Fabric est le nouveau système de rendu de React Native, une évolution conceptuelle du système de rendu hérité ».
Comme JSI expose directement les méthodes natives à JavaScript, y compris les méthodes de l’interface utilisateur, les threads JS et UI peuvent ainsi être synchronisés. Les performances pour les listes, la navigation, la gestion des gestes, etc. s’en trouvent améliorées.
Parmi les changements effectifs, React Native propose maintenant aussi les “Turbo Modules”.
Dans l’architecture précédente, tous les modules natifs utilisés par JavaScript (ex: Bluetooth, Géolocalisation, Stockage de fichiers…) doivent être initialisés avant l’ouverture de l’application. Cela signifie que même si l’utilisateur n’a pas besoin d’un module particulier, celui-ci doit être initialisé au démarrage.
Les “Turbo Modules” sont donc une amélioration permettant à JavaScript de charger chaque module uniquement quand il est nécessaire, en mode “lazy loading”.
Enfin, toutes ces nouveautés dans l’architecture React Native sont appuyées par CodeGen, un vérificateur et générateur de typage permettant à JavaScript, qui a un typage dynamique, d’échanger avec JSI, écrit en C++ et qui par conséquent repose sur un typage statique.
En conclusion
Comme évoqué précédemment, bien que le moteur Hermes et la nouvelle architecture cohabitent déjà au sein des dernières versions de React, Facebook rappelle que ces évolutions ne sont pas encore entièrement stables. Elles sont toujours en cours de travail et d’améliorations dans une version de “release candidate”.
De plus, pour que cette nouvelle version soit totalement utilisable, les packages doivent aussi évoluer et basculer sur cette solution.
React Native vit donc actuellement un moment charnière qui annonce un nouveau souffle à la librairie pour lui promettre encore de beaux jours. Les développeur.se.s peuvent déjà s’amuser à tester le moteur et l’architecture pour y participer.
Néanmoins, cette version n’est pas encore conseillée pour une mise en production.
React Native vs Flutter : l’heure du débat
En premier lieu, il est important de préciser que nous concentrons le débat sur ces deux outils car ils sont les principaux concurrents à l’heure actuelle. Bien évidemment, il existe d’autres frameworks, librairie, etc. tels que Ionic, Native Script, Apache Cordova…
Néanmoins, React Native et Flutter sont les deux seules technologies cross-platform qui se démarquent par leur approche plus orientée native et par leur résultats en termes d’interface utilisateur et de performance.
Au sein de Kaliop, nous avons fait certains choix technologiques comme ceux de proposer essentiellement des PWA (Progressive Web Apps) ou des applications mobiles multiplateformes. Nous pensons que la majeure partie du temps, c’est le meilleur compromis entre les attentes du client, celles des utilisateurs finaux et les résultats. Je vous invite d’ailleurs à lire une étude comparative sur les PWA et les applications mobiles pour comprendre un peu mieux les avantages et les limites de la PWA.
Bien sûr, cela n’enterre pas le développement purement natif avec des langages propriétaires comme Swift ou Kotlin, car il faudra toujours pouvoir proposer des packages qui alimentent le cross-platform en fonctionnalités natives. Néanmoins, il est assez rare de recevoir des projets qui nécessitent un outillage aussi lourd de process.
Dans cette perspective, nous avons donc porté notre dévolu en 2015 sur React Native et construit une première expertise sur cette librairie au sein de plusieurs applications mobiles. Nous avons d’ailleurs réalisé un guide pour partager notre retour d’expérience en présentant les cinq erreurs classiques à éviter avec React Native.
Puis est arrivé Flutter en 2017. Google étant relativement familier des coups d’essais abandonnés quelques mois plus tard, nous avons observé sa trajectoire, car il y a derrière la promesse d’un nouveau framework cross-platform iOS / Android, basé sur un nouveau langage fortement typé, avec hot reload et des performances graphiques incroyables pour des UI poussées. Nous avons donc franchi le pas en 2019 en commençant à former nos équipes et en poussant ce framework sur des projets pour lesquels nous pensions qu’il pouvait convenir.
Jusqu’à récemment, nous avons continué de proposer en parallèle des offres sous React Native et Flutter, en fonction des projets, avec un arbre de décision plutôt simple dans certains cas
Cependant, React Native comme Flutter ont beaucoup progressé et ont changé la donne ces derniers mois.
La nouvelle architecture React Native permet désormais d’obtenir des résultats assez impressionnant en termes UI/UX, réduisant l’écart avec Flutter à peu de choses.
De son côté, la communauté Flutter s’est fortement étendue avec beaucoup de personnes très compétentes et productives, ce qui a entraîné l’apparition d’un nombre impressionnant de nouveaux modules. Ceci a permis notamment un bien meilleur support pour le Desktop. Claire Monnier, développeuse full-stack / mobile chez Kaliop, a rédigé un article sur l’engouement que suscite Flutter ces derniers temps.
Que ce soit en React Native ou en Flutter, la frontière entre les mondes des plateformes devient de plus en plus fine et progresse de jour en jour.
- “Si le projet nécessite du cross-platform mobile et web / desktop : React Native car il y a possibilité de réutiliser une partie de code source pour du React (ou de faire de React Native Web) côté Web et Electron côté Desktop. De plus, React permet de faire du SEO, là où Flutter reste pour le moment une boîte opaque pour le référencement.”
Cela reste encore vrai à l’heure actuelle concernant le SEO.
En revanche, la compatibilité Desktop est devenue comparable entre React Native et Flutter et si le référencement n’est pas un élément de choix, les deux plateformes sont à un niveau comparable pour des applicatifs web. - “Si le projet nécessite une forte propension d’animations poussées sur le mobile : Flutter car l’approche de redessiner toute l’interface utilisateur en canvas apporte de grosses performances et beaucoup de possibilités.”
Cela était vrai il y a encore quelques mois en arrière. Mais les évolutions de React Native et son usage de React Native Reanimated en font maintenant un concurrent à un niveau très similaire. - “Si le projet nécessite une cohérence parfaite en termes UI / UX sur les différents appareils : Flutter car là encore l’approche par canvas permet de se séparer entièrement de la contrainte des composants natifs là où React Native transpose ces derniers.”
Là encore, le temps et le travail ont joué en faveur de React Native qui atteint désormais de nouvelles possibilités pour rendre une UI / UX assez proche de ce que peut faire Flutter. - “Si le projet doit faire appel à des API natives de manière poussée : React Native car le magasin de packages et la communauté de développeurs sont très fournis.”
Cette fois-ci l’argument n’est plus vraiment valable et c’est Flutter qui rattrape rapidement sa jeunesse en fournissant de plus en plus de modules natifs comme la gestion poussée du bluetooth par exemple. - “Si le projet doit être déployé dans un délai très court : React Native car notre organisation interne nous permet d’être plus réactif sur cette librairie.”
Sur ce point, tout est sujet à expérience et désormais au sein de Kaliop, nous avons des équipes qui ont su pousser de beaux projets aussi bien sous React Native que sous Flutter grâce à de fortes montées en compétences et des recrutements. - “Si le client veut aussi un support IoT pour des montres connectées par exemple : Flutter car le bridge est assez puissant.”
Ce point est certainement le plus litigieux car dans le cas de React Native comme dans celui de Flutter, le développement passera forcément par un bridge. Et bien que cela soit possible, l’usage du cross-platform doit être soumis à une étude plus poussée.
En conclusion, le meilleur choix à l’instant T ne sera peut-être plus celui de demain. Donc au sein de Kaliop, nous pensons que la meilleure solution est simplement celle qui permet de rendre heureux les équipes de développement, le client et les utilisateurs finaux.