Interfaccia Javascript (JSI): panoramica e necessità di riarchitettura di react native

Nov 26 2022
React Native è in bundle con molteplici vantaggi come il supporto multipiattaforma, gli aggiornamenti OTA, la ricarica in tempo reale, l'efficienza dei costi, ecc. passaggi richiesti sul ponte. Ma come funziona l'architettura attuale? L'architettura di React Native dipende da tre thread: a) Thread dell'interfaccia utente: questo è il thread principale dell'applicazione utilizzato per il rendering delle viste Android e iOS.

React Native è in bundle con molteplici vantaggi come il supporto multipiattaforma, gli aggiornamenti OTA, la ricarica in tempo reale, l'efficienza dei costi, ecc. passaggi richiesti sul ponte.

Ma come funziona l'architettura attuale?

L'architettura di React Native dipende da tre thread: a) Thread dell'interfaccia utente: questo è il thread principale dell'applicazione utilizzato per il rendering delle viste Android e iOS. b) Shadow thread: è una specie di thread in background che calcola il layout degli elementi (usando Yoga ) prima del rendering sulla piattaforma host. c) Thread JS: JS in bundle che è responsabile della gestione di tutta la logica nella tua applicazione nativa di reazione.


Fonte: FreeCode Camp

L'interazione tra questi thread non è diretta e ogni volta che un thread deve interagire con l'altro thread, deve affrontare il pesante compito di serializzazione e deserializzazione dei dati in JSON per passare oltre il bridge. Ciò si traduce in una copia non necessaria dei dati e questo bridge può essere sovraffollato abbastanza facilmente poiché le operazioni sono asincrone e non ci sono digitazioni rigorose.

Alcune limitazioni dell'attuale architettura:
1. Javascript e il lato nativo non sono a conoscenza l'uno dell'altro e si basano su messaggi JSON asincroni.
2. Tutti i moduli vengono caricati all'avvio, il che aumenta il tempo di interazione.
3. Nessuna priorità delle azioni: le interazioni utente importanti non possono essere prioritarie rispetto alle altre azioni.
4. Serializzazione del bridge
5. Gli elementi dell'interfaccia utente non sono accessibili direttamente dal thread JS.

Architettura corrente di reagire nativo

Presentazione di JSI

Nuova architettura per la reazione nativa

JSI apporta un grande cambiamento nel modo in cui javascript e la parte nativa interagiscono. Fornisce una comunicazione diretta tra i due regni con l'aiuto di un'interfaccia tra JS e C++. Utilizzando l'interfaccia JavaScript, JS può contenere riferimenti a oggetti host e metodi di chiamata su di essi. Con l'aiuto dell'oggetto host ora possiamo usare oggetti nativi nel contesto javascript. Il ponte che era il più grande collo di bottiglia è diviso in parti:

Tessuto

Il nuovo sistema di rendering creato da Facebook che è la ri-architettura del gestore dell'interfaccia utente. Questo renderer è implementato in C++ e il core è condiviso tra le piattaforme. Nella precedente creazione del layout di implementazione prevedeva più passaggi come la serializzazione di JSON e salti attraverso il bridge che presentavano problemi importanti quando il bridge veniva bloccato, ad esempio: cadute di frame durante lo scorrimento di un elenco infinito. La nuova implementazione consente al gestore dell'interfaccia utente di creare Shadow Tree direttamente in C++, il che migliora notevolmente l'esperienza riducendo il numero di salti tra i reami. Le operazioni sono sincrone e thread-safe che vengono eseguite da React (JavaScript) nel renderer (C++), solitamente sul thread JavaScript. Implica anche una minore serializzazione dei dati poiché i valori javascript possono essere prelevati direttamente da JSI. Questo controllo diretto aiuta anche nella definizione delle priorità delle azioni, il renderer ora può dare la priorità a determinate interazioni dell'utente per garantire che vengano gestite in modo tempestivo. Ciò migliorerà notevolmente le prestazioni negli elenchi, nella navigazione e nella gestione dei gesti.

Moduli Turbo

Nell'implementazione precedente, non avevamo il riferimento ai moduli nativi, quindi ogni modulo veniva caricato all'avvio, il che aumenta il TTI (Time to Interactive) ma con i moduli turbo possiamo caricare in modo pigro i moduli come e quando è richiesto, il che aiuterà nel migliorare il tempo di avvio. Ad esempio: se disponi di un modulo per stampare un documento da un collegamento, ora potremmo caricare questo modulo quando atterriamo sulla schermata di stampa e non all'avvio dell'applicazione che veniva eseguito nell'architettura precedente. Anche la possibilità di scrivere il modulo in C++ si aggiunge al vantaggio in quanto riduce l'implementazione duplicata tra le piattaforme.

Codegen

Per incollare tutto questo e rendere compatibili entrambi i regni, il team di React Native ha creato un controllo dei tipi per automatizzare la compatibilità tra JS e il lato nativo. Questo strumento si chiama Codegen. Utilizza un approccio modulare, il che significa che qualsiasi linguaggio Javascript tipizzato staticamente potrebbe essere supportato utilizzando il parser per quel sistema. Utilizzando il JavaScript tipizzato come fonte di verità, questo generatore può definire i file di interfaccia necessari a Fabric e TurboModules per inviare messaggi attraverso i regni con sicurezza. Codegen fornisce anche la sicurezza del tipo in fase di compilazione, il che significa che entrambi gli ambienti possono eseguire comandi senza alcun controllo di runtime, il che significa dimensioni del codice inferiori da spedire e un'esecuzione più rapida.
Dato che ora abbiamo il codice C++ e il C++ è fortemente tipizzato, stiamo forzando la digitazione del nostro codice JS, perché dobbiamo definire i tipi e non possiamo scriverne nessuno da nessuna parte nel codice. Fondamentalmente crea un'interfaccia per te e ora poiché sono generati e sono in C ++, ora possiamo sostanzialmente fidarci dei dati inviati e non dobbiamo andare avanti e indietro per verificare i dati. Ciò significa anche che utilizzando i controlli del tipo possiamo facilmente identificare i problemi durante la fase di sviluppo che avrebbero potuto causare arresti anomali fatali o un'esperienza utente negativa.

Alcuni dei principali vantaggi di JSI

  1. Il codice Javascript può contenere un riferimento a qualsiasi elemento dell'interfaccia utente nativa e chiama i metodi su di esso (simile alla manipolazione DOM nel Web)
  2. Associazioni veloci e dirette al codice nativo che possono migliorare notevolmente le prestazioni, ad esempio MMKV utilizza JSI che è circa 30 volte più veloce di Asyncstorage.
  3. È possibile utilizzare motori diversi da JavaScript Core.
  4. I moduli nativi possono essere caricati quando necessario.
  5. Controllo del tipo statico per rendere compatibile il codice JS e nativo.

JSI nativo di React è attualmente in fase di implementazione sperimentale e man mano che più progetti adotteranno questo cambiamento, conosceremo meglio i limiti e l'impatto della nuova architettura, ma una cosa è certa il futuro dello sviluppo di applicazioni native e multipiattaforma di React sembra eccitante.