Interface Javascript (JSI) : vue d'ensemble et nécessité d'une réarchitecture de réaction native
React Native est fourni avec de multiples avantages tels que la prise en charge multiplateforme, les mises à jour OTA, le rechargement en direct, la rentabilité, etc. laissez-passer requis sur le pont.
Mais comment fonctionne l'architecture actuelle ?
L'architecture de React Native dépend de trois threads : a) Thread d'interface utilisateur : il s'agit du thread d'application principal utilisé pour le rendu des vues Android et iOS. b) Fil d'ombre : C'est une sorte de fil d'arrière-plan qui calcule la disposition des éléments (à l'aide de Yoga ) avant le rendu sur la plate-forme hôte. c) Thread JS : JS groupé qui est responsable de la gestion de toute la logique de votre application native de réaction.
L'interaction entre ces threads n'est pas directe et chaque fois qu'un thread doit interagir avec l'autre thread, il doit passer par la lourde tâche de sérialisation et de désérialisation des données vers JSON pour passer par le pont. Cela entraîne une copie inutile des données et ce pont peut facilement être encombré car les opérations sont asynchrones et il n'y a pas de typage strict.
Certaines limitations de l'architecture actuelle :
1. Javascript et le côté natif ne se connaissent pas et s'appuient sur des messages JSON asynchrones.
2. Tous les modules se chargent au démarrage, ce qui augmente le temps d'interaction.
3. Aucune priorisation des actions : les interactions importantes des utilisateurs ne peuvent pas être prioritaires par rapport aux autres actions.
4. Sérialisation de pont
5. Les éléments de l'interface utilisateur ne sont pas accessibles directement à partir du thread JS.
Présentation de JSI
JSI apporte un grand changement dans la façon dont le javascript et la partie native interagissent. Il fournit une communication directe entre les deux domaines à l'aide d'une interface entre JS et C++. À l'aide de l'interface JavaScript, JS peut contenir des références aux objets hôtes et appeler des méthodes sur ceux-ci. Avec l'aide de l'objet hôte, nous pouvons maintenant utiliser des objets natifs dans le contexte javascript. Le pont qui était le plus gros goulot d'étranglement est divisé en plusieurs parties :
Tissu
Le nouveau système de rendu créé par Facebook qui est la ré-architecture du gestionnaire d'interface utilisateur. Ce moteur de rendu est implémenté en C++ et le noyau est partagé entre les plates-formes. Dans l'implémentation précédente, la création de la mise en page impliquait plusieurs étapes telles que la sérialisation de JSON et les sauts à travers le pont, ce qui posait des problèmes majeurs lorsque le pont était bloqué, par exemple : des chutes de trame lors du défilement d'une liste infinie. La nouvelle implémentation permet au gestionnaire de l'interface utilisateur de créer l'arbre fantôme directement en C++, ce qui améliore considérablement l'expérience en réduisant le nombre de sauts entre les royaumes. Les opérations sont synchrones et thread-safe qui sont exécutées à partir de React (JavaScript) dans le moteur de rendu (C++), généralement sur le thread JavaScript. Cela implique également moins de sérialisation des données car les valeurs javascript peuvent être directement extraites de JSI. Ce contrôle direct aide également à hiérarchiser les actions, le moteur de rendu peut désormais hiérarchiser certaines interactions utilisateur pour s'assurer qu'elles sont traitées en temps opportun. Cela améliorera considérablement les performances dans les listes, la navigation et la gestion des gestes.
Modules turbo
Dans l'implémentation précédente, nous n'avions pas la référence aux modules natifs, donc chaque module était chargé au démarrage, ce qui augmente le TTI (Time to Interactive), mais avec les modules turbo, nous pouvons charger paresseux les modules au fur et à mesure des besoins, ce qui aidera dans l'amélioration du temps de démarrage. Par exemple : Si vous avez un module pour imprimer un document à partir d'un lien, on pourrait maintenant charger ce module quand on atterrit sur l'écran d'impression et non plus au démarrage de l'application ce qui se faisait dans l'architecture précédente. La possibilité d'écrire le module en C++ ajoute également à l'avantage car elle réduit l'implémentation en double sur les plates-formes.
Codegen
Pour coller tout cela ensemble et rendre les deux royaumes compatibles, l'équipe React Native a construit un vérificateur de type pour automatiser la compatibilité entre JS et le côté natif. Cet outil s'appelle Codegen. Il utilise une approche modulaire, ce qui signifie que tout langage Javascript typé statiquement peut être pris en charge en utilisant l'analyseur pour ce système. En utilisant le JavaScript typé comme source de vérité, ce générateur peut définir les fichiers d'interface nécessaires à Fabric et aux TurboModules pour envoyer des messages à travers les royaumes en toute confiance. Codegen fournit également une sécurité de type au moment de la compilation, ce qui signifie que les deux environnements peuvent exécuter des commandes sans aucun contrôle d'exécution, ce qui signifie une taille de code plus petite à expédier et une exécution plus rapide.
Puisque nous avons maintenant du code C++ et que C++ est fortement typé, nous forçons en quelque sorte notre code JS à être typé, car nous devons définir des types et ne pouvons en écrire nulle part dans le code. Il crée essentiellement une interface pour vous et maintenant, puisqu'ils sont générés et sont en C++, nous pouvons désormais faire confiance aux données envoyées et nous n'avons pas à aller et venir pour vérifier les données. Cela signifie également qu'en utilisant les vérifications de type, nous pouvons facilement identifier les problèmes au cours de la phase de développement qui auraient pu entraîner des plantages fatals ou une mauvaise expérience utilisateur.
Quelques avantages majeurs de JSI
- Le code Javascript peut contenir une référence à tous les éléments de l'interface utilisateur native et appeler les méthodes dessus (similaire à la manipulation DOM dans le Web)
- Liaisons rapides et directes au code natif qui peuvent grandement améliorer les performances, par exemple MMKV utilise JSI qui est ~30x plus rapide qu'Asyncstorage.
- Des moteurs autres que JavaScript Core peuvent être utilisés.
- Les modules natifs peuvent être chargés en cas de besoin.
- Vérification de type statique pour rendre compatible le JS et le code natif.
React native JSI est actuellement en phase de déploiement expérimental et au fur et à mesure que de plus en plus de projets adoptent ce changement, nous en apprendrons davantage sur les limites et l'impact de la nouvelle architecture, mais une chose est sûre, l'avenir du développement d'applications natives et multiplateformes de React. semble passionnant.