Si vous êtes nouveau sur React, vous pouvez en lire plus sur le site web de React. Vous pouvez également commencer avec React Native pour iOS, qui a été publié à F8 2015 sur le site Web de React Native.
Cela a commencé avec React
Il y a deux ans, React a été présenté au monde, et depuis lors, il a connu une croissance impressionnante, tant à l’intérieur qu’à l’extérieur de Facebook. Aujourd’hui, même si personne n’est obligé de l’utiliser, de nouveaux projets Web sur Facebook sont généralement construits en utilisant React sous une forme ou une autre, et il est largement adopté dans l’industrie. Les ingénieurs choisissent d’utiliser React tous les jours parce que cela leur permet de consacrer plus de temps à la mise au point de leurs produits et moins de temps à se battre avec leur cadre applicatif. Ce n’est qu’après avoir construit avec React pendant un moment que nous avons commencé à comprendre ce qui le rend si puissant.
React nous oblige à décomposer nos applications en composants discrets, chacun représente une vue unique. Ces composants facilitent l’itérer sur nos produits, car nous n’avons pas besoin de garder le système entier dans notre tête afin d’apporter des modifications à une partie de celui-ci. Plus important encore, React enveloppe l’API impérative mutative du DOM d’une API déclarative, ce qui augmente le niveau d’abstraction et simplifie le modèle de programmation. Ce que l’on peut trouver, c’est que lorsque nous construisons avec React, notre code est beaucoup plus prévisible. Cette prévisibilité nous permet de parcourir plus rapidement et en toute confiance, ce qui rend nos applications beaucoup plus fiables. De plus, il est non seulement plus facile de faire évoluer nos applications lorsqu’elles sont construites avec React, mais on peut également constater qu’il est plus facile d’augmenter la taille de nos équipes elles-mêmes.
Avec le cycle d’itération rapide du Web, on peut se permettre de créer des produits géniaux avec React, y compris de nombreux composants de Facebook.com. De plus, on peut construire des frameworks étonnants en JavaScript au-dessus de React, comme Relay, ce qui nous permet de simplifier considérablement la collecte de données à grande échelle. Bien sûr, le web n’est qu’une partie de l’histoire. Facebook a également largement utilisé les applications Android et iOS, qui sont construites sur des piles de technologie propriétaires disjointes. Le fait de devoir construire nos applications sur plusieurs plate-formes a bifurqué notre organisation d’ingénierie, mais ce n’est que l’une des choses qui rendent difficile le développement des applications mobiles natives.
Pourquoi Native est difficile ?
L’environnement mobile Native est plus difficile à utiliser que le Web pour de nombreuses raisons. D’une part, il est plus difficile de faire apparaître les choses à l’écran, et nous devons souvent calculer manuellement la taille et la position de toutes nos vues. Nous n’avons pas non plus accès à React ou Relay, ce qui a facilité le développement de sites Web et la croissance de notre organisation d’ingénierie. L’une des choses les plus douloureuses de notre transition vers le mobile, cependant, est de savoir à quel point cela a ralenti notre vitesse de développement.
En construisant sur le web, nous pouvons simplement sauvegarder nos fichiers et recharger le navigateur pour voir le résultat de nos changements. Sur Native, cependant, nous devons recompiler après chaque changement, même si nous voulons simplement déplacer le texte de quelques pixels sur l’écran. En conséquence, les ingénieurs finissent par travailler beaucoup plus lentement, surtout dans un grand code où la compilation est particulièrement lourde. Construire sur Native rend également le test de nouvelles fonctionnalités plus difficile. Sur Facebook, on peut livrer une nouvelle version du site deux fois par jour, ce qui nous permet de récupérer les résultats d’une expérience presque immédiatement. Sur mobile, on doit 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 notre application sont publiées beaucoup moins souvent. « Aller plus vite » est dans l’ADN de Facebook, mais nous ne pouvons pas aller aussi vite sur mobile que nous le pouvons sur le web. Alors pourquoi faire le changement en premier lieu ?
La raison pour laquelle nous construisons des applications natives sur ces plates-formes propriétaires est qu’en ce moment, nous pouvons créer des expériences de meilleure qualité qui sont plus cohérentes avec le reste de la plateforme que nous ne le pouvons sur le web.
Pourquoi Native est nécessaire ?
Même si le développement des applications mobiles prend plus de temps, il existe de nombreuses raisons pour nous aider à obtenir des expériences sur les plateformes mobiles que sur le Web. D’une part, nous avons accès à des composants d’interface utilisateur spécifiques à une plate-forme, tels que des cartes, des sélecteurs de date, des commutateurs et des piles de navigation. Il est possible de réimplémenter ces composants sur le Web, mais nos réimplémentations ne se trouvent jamais exactement comme leurs homologues natifs, et elles ne sont pas mises à jour automatiquement avec les modifications apportées à la plate-forme. Nous n’avons également rien d’aussi sophistiqué que les outils de reconnaissance de gestes mobiles sur le web, et nous ne disposons pas encore de l’outillage approprié ou de la discipline nécessaire pour créer un système qui convienne parfaitement à cela.
Sur le web, nous n’avons pas non plus de modèle de fil sophistiqué, donc nous ne pouvons pas paralléliser le travail sur plusieurs threads. Nous pouvons essayer d’utiliser des web workers pour exécuter une partie de notre logique d’application en arrière-plan, mais nous ne pouvons pas encore effectuer un calcul numérique comme le décodage d’image ou la mesure de texte sur l’élément principal du navigateur. C’est probablement un des plus grands défis de la construction des applications web performantes et réactives.
Le meilleur des deux mondes ?
Ce que nous voulons vraiment, c’est l’expérience utilisateur des plates-formes mobiles natives, combinée à l’expérience du développeur que nous avons en construisant avec React sur le web. Il existe probablement plusieurs façons d’y parvenir :
1. Utilisation de WebViews
Une possibilité consiste à utiliser WebViews dans des applications d’enveloppeur natives simples. C’est une excellente idée. Bien que notre implémentation ne nous donne pas la performance et la mise à l’échelle souhaitées, cette approche est remarquablement flexible et présente tous les avantages associés à l’expérience du développeur sur le Web, comme la possibilité de tirer parti de React et du cycle d’itération rapide du Web. . Malheureusement, parce que tout le rendu est fait en utilisant la technologie web, on ne peut pas produire une expérience utilisateur vraiment native.
2. Porter React à Native
Porter React au code Native est également une excellente idée, et en fait, cela a été construit pour iOS ! Ce projet s’appelle ComponentKit. Avec ComponentKit, nous obtenons tous les avantages de React, en particulier déclarative et interfaces utilisateurs prévisibles, mais nous pouvons également tirer parti de la puissance de l’environnement Native, avec des composants spécifiques à la plateforme et la manipulation des gestes sophistiqués, ainsi que le décodage d’image asynchrone, la mesure du texte et le rendu. De plus, étant donné que ComponentKit utilise flexbox pour la mise en page, on n’a pas besoin de positionner et de dimensionner manuellement les vues dans votre application, de sorte que votre code finisse par être plus concis et plus facile à maintenir.
Cependant, il y a quelques inconvénients mineurs à cette approche. Tout d’abord, c’est destiné à iOS seulement, donc si nous voulons en profiter sur un appareil Android, nous devrons construire une implémentation séparée, et apprendre aux ingénieurs comment l’utiliser. De plus, nous n’avons accès à aucun des éléments que nous avons créés pour le web en plus de React, comme Relay, ce qui nous aide à résoudre les problèmes réels auxquels nous avons dû faire face en augmentant la récupération de nos données. Le plus important, cependant, est que nous n’avons pas fondamentalement amélioré notre défi de vitesse de développement – nous devons encore recompiler après chaque changement.
3. Scripter Native
Si nous utilisons JavaScript pour faire appel à des API natives, nous devrions avoir accès à toute la puissance de l’environnement Native, mais nous devrions également pouvoir itérer rapidement et tirer parti de notre infrastructure JavaScript existante. De plus, étant donné qu’il ne s’agit que de JavaScript, nous pourrions probablement faire fonctionner cette pile sur plusieurs plates-formes. Cela ressemble à tout ce que nous voulons, et il n’est pas surprenant qu’il y ait des tonnes de cadres applicatifs pour le faire. Mais ce n’est pas vraiment si simple.
Scripter Native est difficile
Si nous appelons simplement un aller-retour de façon synchrone entre l’environnement Native et un environnement interprété, notre thread d’interface utilisateur pourrait être bloqué lors de l’exécution de JavaScript. Pour le rendre efficace, nous savons que nous voulons exécuter notre JavaScript sur le thread principal, mais cela est difficile. La première raison pour laquelle cela est difficile est la contention des ressources. Si notre code JavaScript accède à quelque chose qui pourrait représenter une ressource sur un autre thread – les dimensions d’une vue rendue, par exemple – le système doit se verrouiller, ce qui peut provoquer des décrochages dans l’interface utilisateur. La deuxième raison pour laquelle cela est difficile est qu’il y a une quantité fixe de surcoût associée à chaque aller-retour entre l’environnement Native et la machine virtuelle JavaScript. Si nous avons souvent besoin de franchir la frontière du thread, nous devrons encaisser ce surcoût encore et encore.
Donc, si nous ne le faisons pas correctement, notre application pourrait finir par se sentir pire que si elle était entièrement écrite en code Native ou en JavaScript. Nous ne pouvons pas simplement réimplémenter des API d’interface utilisateur synchrones et impératives en JavaScript et nous espérons obtenir une expérience sensible et native. Nous devons fondamentalement changer le modèle de programmation et veiller à ce que notre système transmette toujours les messages à travers la limite de thread de manière asynchrone et que nous puissions traiter autant de ces messages par trame que possible, en minimisant les surcoûts de communication.
Heureusement, React nous donne le modèle de programmation parfait pour le faire correctement.
Présentation de React Native
Puisque les composants React ne sont que des fonctions pures et sans effets secondaires qui renvoient à quoi ressemblent nos vues à tout moment, nous n’avons jamais besoin de lire à partir de l’implémentation de la vue rendue sous-jacente pour y écrire. Dans l’environnement du navigateur, React est non-bloquant par rapport au DOM, mais l’avantage de React est qu’il est abstrait et pas étroitement couplé au DOM. React peut envelopper n’importe quel système de vue impératif, comme UIKit sur iOS, par exemple.
Donc, cela signifie qu’avec un peu de travail, nous pouvons faire en sorte que la même React sur GitHub puisse alimenter des applications mobiles vraiment natives. La seule différence dans l’environnement mobile est qu’au lieu d’exécuter React dans le navigateur et de rendre les divs et les spans, nous l’exécutons dans une instance intégrée de JavaScriptCore dans nos applications et restituons des composants spécifiques à la plate-forme à un niveau élevé.
L’une des meilleures choses à propos de cette approche est que nous pouvons l’adopter de manière progressive, en construisant de nouveaux produits en plus de cela ou en convertissant de vieux produits pour les utiliser n’importe quand et n’importe où. Tout comme nous n’avions pas besoin de réécrire l’intégralité de Facebook.com pour commencer à utiliser React à certains endroits, nous n’avons pas besoin de reconstruire l’intégralité de nos applications Facebook mobiles pour commencer à tirer parti des avantages de React Native.
Cela fonctionne
React Native a été utilisé en production sur Facebook depuis un certain temps maintenant, et même s’il reste encore beaucoup de travail à faire, cela fonctionne très bien pour nous. Il est important de noter que nous ne poursuivons pas l’approche « écrire une fois, exécuter n’importe où ». Différentes plates-formes ont des aspects, des sensations et des capacités différents, et nous devrions donc développer des applications discrètes pour chaque plate-forme, mais le même ensemble d’ingénieurs devrait être capable de créer des applications pour n’importe quelle plate-forme, sans avoir besoin d’apprendre un ensemble fondamentalement différent de technologies pour chacun. On appelle cette approche par « apprendre une fois, écrire n’importe où ».
Si vous avez un iPhone, vous pouvez tester quelques applications en utilisant React Native qui sont disponibles sur l’App Store. Facebook Groups est une application hybride, composée de vues construites à la fois avec du code Native et React Native JavaScript, et Facebook Ads Manager est entièrement construit en utilisant React Native.
Open source
La mission du Facebook est de rendre le monde plus ouvert et connecté, et pour contribuer activement à cette mission via l’open source, React Native ne fait pas exception. Les problèmes auxquels sont confrontés l’entreprise d’ingénierie ne sont pas uniquement pour elle et, par conséquent, elle souhaite développer autant que possible, en collaboration avec d’autres qui font face aux mêmes défis.
Aujourd’hui, React Native est disponible pour iOS et bientôt, on pourra l’obtenir sur GitHub. Cela nécessite l’arrivée du support d’Android. En attendant, React continue à aller de l’avant pour le web. Gardez à l’esprit toutefois qu’il y a probablement beaucoup de choses qui ne sont pas encore implémentées sur ce support pour iOS.