React Native nova arhitektura 2026: Vodič kroz JSI, Fabric, TurboModules i Bridgeless Mode

Potpuni vodič kroz novu arhitekturu React Nativea u 2026. Saznajte kako JSI, Fabric, TurboModules i Bridgeless Mode poboljšavaju performanse mobilnih aplikacija, uz praktične primjere koda i detaljne upute za migraciju.

Uvod u Novu Arhitekturu React Nativea

React Native prešao je prilično dug put od 2015. godine. Ono što je krenulo kao pomalo eksperimentalni okvir za izradu mobilnih aplikacija u JavaScriptu danas je ozbiljna platforma koja pokreće tisuće aplikacija — od malih startupova do kompanija poput Mete, Shopifyja i Microsofta. Ali jedna od najbitnijih promjena u cijeloj povijesti React Nativea dogodila se upravo u posljednje dvije godine: potpuna transformacija unutarnje arhitekture.

Dakle, o čemu se zapravo radi?

Nova Arhitektura React Nativea (eng. New Architecture) predstavlja fundamentalnu promjenu u načinu na koji JavaScript komunicira s nativnim kodom. Umjesto starog asinkronog mosta (eng. bridge), koji je godinama bio usko grlo za performanse, nova arhitektura uvodi izravnu, sinkronu komunikaciju putem JSI (JavaScript Interface), novi sustav renderiranja nazvan Fabric, te modernizirane nativne module — TurboModules. Od verzije React Native 0.82, nova arhitektura je jedini podržani način rada, a u Expo SDK 55 (siječanj 2026.) više se ne može ni isključiti.

U ovom vodiču detaljno ćemo proći sve komponente nove arhitekture, objasniti kako funkcioniraju, pokazati praktične primjere koda i pružiti korak-po-korak upute za migraciju postojećih projekata. Bilo da ste iskusni React Native developer ili tek počinjete, razumijevanje nove arhitekture je ključno za razvoj performantnih mobilnih aplikacija u 2026. godini.

Problemi stare arhitekture: Zašto je most bio usko grlo

Da bismo potpuno shvatili prednosti nove arhitekture, moramo najprije razumjeti ograničenja stare. Klasična React Native arhitektura temeljila se na tri glavne niti:

  • JavaScript nit — izvršava JavaScript kod, upravlja poslovnom logikom i React stablom komponenata
  • Nativna nit (Main/UI thread) — odgovorna za renderiranje nativnih UI komponenata i obradu korisničkih interakcija
  • Shadow nit — izračunava raspored elemenata (layout) koristeći Yoga engine

Komunikacija između ovih niti odvijala se putem asinkronog mosta (bridge). Svaka poruka morala je proći serijalizaciju u JSON format, prijenos preko mosta, pa deserijalizaciju na drugoj strani. I tu su nastajali problemi:

  • Latencija — Serijalizacija i deserijalizacija JSON podataka zahtijevala je dodatno vrijeme, posebno kod velikih struktura podataka
  • Asinkronost — Budući da je komunikacija bila asinkrona, nije bilo moguće sinkrono pristupiti nativnim resursima iz JavaScripta
  • Zagušenje — Pri intenzivnom korištenju (npr. brze animacije, česte promjene layouta), most bi se jednostavno zagušio porukama, što je uzrokovalo padove broja okvira (frame drops)
  • Učitavanje svih modula pri pokretanju — Svi nativni moduli inicijalizirali su se prilikom pokretanja aplikacije, čak i oni koji se nikada neće koristiti. To je nepotrebno produljivalo vrijeme pokretanja

Ovi problemi su bili posebno vidljivi na uređajima slabijih performansi, gdje je zagušenje mosta moglo dovesti do primjetnog zastajkivanja sučelja i sporih animacija. Iskreno, tko je ikada radio s React Nativeom na starijem Android uređaju, zna koliko je to moglo biti frustrirajuće.

JSI: Temelj nove komunikacije

JavaScript Interface (JSI) je srce nove arhitekture. Radi se o laganom, niskoj razini sučelju napisanom u C++ koje omogućuje JavaScriptu izravno držanje referenci na C++ objekte — i obrnuto. To znači da JavaScript može pozivati nativne metode sinkrono, bez ikakve serijalizacije podataka u JSON.

Kako JSI funkcionira

JSI zamjenjuje stari most izravnim vezama između JavaScripta i nativnog koda. Umjesto slanja poruka kroz red čekanja, JavaScript sada može:

  • Izravno pozivati C++ funkcije
  • Držati reference na nativne objekte
  • Pristupati nativnim podacima bez kopiranja (zero-copy)
  • Koristiti sinkrone i asinkrone pozive prema potrebi

Evo pojednostavljenog prikaza razlike:

// Stari pristup (Bridge)
// JavaScript → JSON serijalizacija → Bridge → JSON deserijalizacija → Native
// Native → JSON serijalizacija → Bridge → JSON deserijalizacija → JavaScript

// Novi pristup (JSI)
// JavaScript ←→ JSI (C++) ←→ Native
// Izravna komunikacija, bez serijalizacije

JSI je također agnostičan prema JavaScript enginu — i to je zapravo jako bitno. React Native više nije vezan isključivo za JavaScriptCore. Može koristiti Hermes (koji je danas zadani engine), V8 ili bilo koji drugi JavaScript engine koji implementira JSI sučelje.

Prednosti JSI-ja u praksi

Praktične prednosti su prilično značajne:

  • Brže animacije — Sinkrona komunikacija omogućuje glatke animacije na 60+ FPS bez zastajkivanja
  • Brži pristup podacima — Nema više čekanja na serijalizaciju i deserijalizaciju
  • Manji memorijski otisak — Zero-copy pristup podacima smanjuje korištenje memorije
  • Fleksibilnost — Mogućnost korištenja različitih JavaScript enginea

TurboModules: Sljedeća generacija nativnih modula

TurboModules su nasljednici klasičnih NativeModules. Koriste JSI za izravnu komunikaciju s nativnim kodom i donose nekoliko ključnih poboljšanja koja stvarno utječu na performanse i razvojno iskustvo.

Ključne razlike od starih NativeModules

  • Lijeno učitavanje (lazy loading) — TurboModules se inicijaliziraju tek kada ih aplikacija prvi put zatraži, umjesto pri pokretanju. To dramatično smanjuje vrijeme pokretanja aplikacije
  • Tipski sigurni — Koriste Codegen za generiranje nativnog koda iz TypeScript/Flow specifikacija, osiguravajući tipsku sigurnost na obje strane
  • Sinkroni pozivi — Mogu izvoditi sinkrone pozive kada je to potrebno, zahvaljujući JSI-ju
  • Bolje upravljanje memorijom — Dijele memoriju između JavaScripta i nativnog koda bez kopiranja

Kreiranje TurboModula: Korak po korak

Ajmo proći kroz kreiranje TurboModula. Sve započinje definiranjem TypeScript specifikacije — Codegen koristi tu specifikaciju za automatsko generiranje nativnog koda. Datoteka mora pratiti konvenciju imenovanja Native{ImeModula}.ts.

Korak 1: Definiranje TypeScript specifikacije

// specs/NativeDeviceInfo.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';

export interface Spec extends TurboModule {
  getDeviceModel(): Promise<string>;
  getBatteryLevel(): Promise<number>;
  getStorageInfo(): Promise<{
    totalSpace: number;
    freeSpace: number;
  }>;
  isCharging(): boolean; // sinkroni poziv
}

export default TurboModuleRegistry.getEnforcing<Spec>(
  'NativeDeviceInfo'
);

Korak 2: Konfiguriranje Codegen-a

U package.json dodajte konfiguraciju:

{
  "codegenConfig": {
    "name": "NativeDeviceInfoSpec",
    "type": "modules",
    "jsSrcsDir": "specs",
    "android": {
      "javaPackageName": "com.myapp.deviceinfo"
    }
  }
}

Korak 3: Implementacija na iOS-u (Objective-C++)

// ios/NativeDeviceInfo.mm
#import <NativeDeviceInfoSpec/NativeDeviceInfoSpec.h>
#import <UIKit/UIKit.h>

@interface NativeDeviceInfo : NSObject <NativeDeviceInfoSpec>
@end

@implementation NativeDeviceInfo

RCT_EXPORT_MODULE()

- (void)getDeviceModel:(RCTPromiseResolveBlock)resolve
                reject:(RCTPromiseRejectBlock)reject {
  resolve([[UIDevice currentDevice] model]);
}

- (void)getBatteryLevel:(RCTPromiseResolveBlock)resolve
                 reject:(RCTPromiseRejectBlock)reject {
  [UIDevice currentDevice].batteryMonitoringEnabled = YES;
  float level = [UIDevice currentDevice].batteryLevel;
  resolve(@(level * 100));
}

- (NSNumber *)isCharging {
  [UIDevice currentDevice].batteryMonitoringEnabled = YES;
  UIDeviceBatteryState state = [UIDevice currentDevice].batteryState;
  return @(state == UIDeviceBatteryStateCharging);
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
    (const facebook::react::ObjCTurboModule::InitParams &)params {
  return std::make_shared<facebook::react::NativeDeviceInfoSpecJSI>(
    params
  );
}

@end

Korak 4: Korištenje u aplikaciji

// App.tsx
import NativeDeviceInfo from './specs/NativeDeviceInfo';

async function prikaziInfoUredaja() {
  const model = await NativeDeviceInfo.getDeviceModel();
  const baterija = await NativeDeviceInfo.getBatteryLevel();
  const puni = NativeDeviceInfo.isCharging(); // sinkroni poziv!

  console.log(`Model: ${model}`);
  console.log(`Baterija: ${baterija}%`);
  console.log(`Punjenje: ${puni ? 'Da' : 'Ne'}`);
}

// Korištenje u React komponenti
import React, { useEffect, useState } from 'react';
import { View, Text } from 'react-native';

function DeviceInfoScreen() {
  const [info, setInfo] = useState<{
    model: string;
    battery: number;
  } | null>(null);

  useEffect(() => {
    async function ucitaj() {
      const model = await NativeDeviceInfo.getDeviceModel();
      const battery = await NativeDeviceInfo.getBatteryLevel();
      setInfo({ model, battery });
    }
    ucitaj();
  }, []);

  if (!info) return <Text>Učitavanje...</Text>;

  return (
    <View>
      <Text>Uređaj: {info.model}</Text>
      <Text>Baterija: {info.battery}%</Text>
    </View>
  );
}

Fabric: Novi sustav renderiranja

Fabric je potpuno novi sustav renderiranja koji zamjenjuje stari UIManager. Dok je stari sustav koristio most za komunikaciju između React stabla i nativnih pogleda, Fabric koristi JSI za izravnu manipulaciju nativnim komponentama iz C++ koda. To je, jednostavno rečeno, ogromna razlika u praksi.

Ključne karakteristike Fabrica

  • Konkurentno renderiranje — Fabric podržava Concurrent React značajke poput Suspense, Transitions i automatskog grupiranja ažuriranja (batching), što omogućuje responzivnije korisničko sučelje
  • Dijeljeni C++ jezgreni kod — Logika renderiranja dijeli se između iOS-a i Androida, smanjujući nedosljednosti među platformama
  • Sinkroni pristup layoutu — Moguće je sinkrono čitati raspored elemenata, što je ključno za glatke animacije i geste
  • Poboljšana tipska sigurnost — Codegen generira tipski siguran kod za Fabric komponente, smanjujući mogućnost runtime pogrešaka

Kreiranje Fabric Native komponente

Fabric komponente koriste sličan pristup kao TurboModules — započinjete s TypeScript specifikacijom.

Korak 1: TypeScript specifikacija za komponentu

// specs/ProgressBarNativeComponent.ts
import type { ViewProps } from 'react-native';
import type {
  Float,
  Int32,
  WithDefault,
} from 'react-native/Libraries/Types/CodegenTypes';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';

interface NativeProps extends ViewProps {
  progress: Float;            // Vrijednost napretka (0.0 - 1.0)
  color?: string;             // Boja trake
  trackColor?: string;        // Boja pozadine trake
  animated?: WithDefault<boolean, true>; // Animirani prijelazi
  thickness?: WithDefault<Int32, 4>;     // Debljina trake u pikselima
}

export default codegenNativeComponent<NativeProps>(
  'ProgressBarView'
);

Korak 2: Korištenje komponente u aplikaciji

import React, { useState, useEffect } from 'react';
import { View, Button, StyleSheet } from 'react-native';
import ProgressBarView from './specs/ProgressBarNativeComponent';

function DownloadScreen() {
  const [progress, setProgress] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setProgress(prev => {
        if (prev >= 1) {
          clearInterval(interval);
          return 1;
        }
        return prev + 0.01;
      });
    }, 100);
    return () => clearInterval(interval);
  }, []);

  return (
    <View style={styles.container}>
      <ProgressBarView
        progress={progress}
        color="#4CAF50"
        trackColor="#E0E0E0"
        animated={true}
        thickness={8}
        style={styles.progressBar}
      />
      <Button
        title="Resetiraj"
        onPress={() => setProgress(0)}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    padding: 20,
  },
  progressBar: {
    height: 20,
    width: '100%',
    marginBottom: 20,
  },
});

Bridgeless Mode: Potpuno uklanjanje mosta

Bridgeless Mode je posljednji korak u evoluciji nove arhitekture — i nekako najzadovoljavajući. Dok su TurboModules i Fabric već zaobišli most za većinu operacija, Bridgeless Mode potpuno uklanja sve preostale ovisnosti o starom mostu. To uključuje interne sustave poput upravljanja događajima i vremenskim intervalima koji su prethodno još uvijek koristili bridge.

Što se mijenja u Bridgeless modu

  • Event sustav — Događaji (touch, scroll, keyboard) sada prolaze izravno kroz JSI umjesto kroz most
  • Timer sustavsetTimeout, setInterval i requestAnimationFrame koriste nativne implementacije bez mosta
  • Modul registracija — Moduli se registriraju izravno u JSI runtime umjesto kroz stari bridge registry
  • Error handling — Greške se propagiraju izravno, što omogućuje bolje stack trace poruke i brže debugiranje

Utjecaj na performanse

Prema testiranjima u produkcijskim okruženjima, Bridgeless Mode donosi zaista značajna poboljšanja:

  • Time-To-Interactive (TTI) — smanjenje do 50% zahvaljujući eliminaciji overhead-a mosta i lijenom učitavanju modula
  • Memorijsko korištenje — smanjenje za 10-20% jer nema potrebe za održavanjem struktura podataka vezanih uz most
  • Glatkoća animacija — konzistentnih 60 FPS čak i na slabijim uređajima zahvaljujući sinkronoj komunikaciji

Codegen: Automatsko generiranje koda

Codegen je alat koji automatski generira nativni kod (C++, Objective-C++, Java) iz vaših TypeScript ili Flow specifikacija. Možete ga zamisliti kao ljepilo koje povezuje JavaScript tipove s nativnim implementacijama, osiguravajući tipsku sigurnost preko granica programskih jezika.

Kako Codegen funkcionira

Proces je relativno jednostavan:

  1. Definirate TypeScript sučelje za svoj modul ili komponentu
  2. Codegen analizira specifikaciju i identificira tipove, metode i svojstva
  3. Automatski generira nativni kod za iOS (Objective-C++) i Android (Java/Kotlin)
  4. Generirani kod uključuje tipski sigurne omotače, serijalizacijske metode i JNI/ObjC mostove
// Pokretanje Codegen-a
// Za Expo projekte - automatski se pokreće pri gradnji
npx expo prebuild

// Za bare React Native projekte
npx react-native codegen

// Konfiguracija u package.json
{
  "codegenConfig": {
    "name": "AppSpecs",
    "type": "all",
    "jsSrcsDir": "specs",
    "android": {
      "javaPackageName": "com.myapp"
    }
  }
}

Podržani tipovi u Codegen-u

Codegen podržava širok raspon TypeScript tipova koji se mapiraju na odgovarajuće nativne tipove:

  • stringNSString (iOS) / String (Android)
  • numberdouble na obje platforme
  • booleanBOOL (iOS) / boolean (Android)
  • Float / Int32 → specifični numerički tipovi
  • Promise<T> → asinkroni pozivi s resolve/reject
  • Objekti i nizovi → odgovarajuće nativne strukture
  • WithDefault<T, defaultValue> → svojstva sa zadanim vrijednostima

Hermes v1: Optimizirani JavaScript engine

Hermes je JavaScript engine koji je Meta razvila specifično za React Native. Hermes v1, koji dolazi s Expo SDK 55, donosi značajna poboljšanja performansi i podršku za moderne JavaScript značajke.

Ključna poboljšanja Hermes v1

  • Brže pokretanje — Hermes kompilira JavaScript u bytecode tijekom izgradnje aplikacije (AOT kompilacija), eliminirajući potrebu za parsiranjem i kompiliranjem u runtime-u
  • Poboljšana podrška za moderne JS — Bolja podrška za ES2023+ značajke, uključujući Array.prototype.toSorted(), Object.groupBy() i dekoratore
  • Optimizirano upravljanje memorijom — Napredniji garbage collector s manjim pauzama
  • Profiliranje performansi — Ugrađeni alati za praćenje koji omogućuju snimanje sesija unutar aplikacije
// Provjera je li Hermes aktivan
const isHermes = () => !!global.HermesInternal;

console.log('Hermes engine:', isHermes() ? 'Aktivan' : 'Neaktivan');

// Korištenje modernih JS značajki s Hermes v1
const brojevi = [3, 1, 4, 1, 5, 9, 2, 6];
const sortirano = brojevi.toSorted(); // Ne mijenja originalni niz
console.log(sortirano); // [1, 1, 2, 3, 4, 5, 6, 9]

const korisnici = [
  { ime: 'Ana', grad: 'Zagreb' },
  { ime: 'Marko', grad: 'Split' },
  { ime: 'Ivana', grad: 'Zagreb' },
];
const poGradu = Object.groupBy(korisnici, k => k.grad);
// { Zagreb: [...], Split: [...] }

Praćenje performansi u novoj arhitekturi

Nova arhitektura donosi i napredne alate za praćenje performansi. Expo SDK 55 uvodi Performance Tracing koji omogućuje detaljnu analizu izvršavanja aplikacije — nešto što nam je definitivno nedostajalo u ranijim verzijama.

Korištenje Performance Tracinga

import { Performance } from 'react-native';

// Mjerenje vremena izvršavanja operacije
performance.mark('pocetak-ucitavanja');

// ... izvršavanje operacije ...

performance.mark('kraj-ucitavanja');
performance.measure(
  'ucitavanje-podataka',
  'pocetak-ucitavanja',
  'kraj-ucitavanja'
);

// Dohvaćanje mjerenja
const mjere = performance.getEntriesByType('measure');
mjere.forEach(m => {
  console.log(`${m.name}: ${m.duration}ms`);
});

React DevTools Profiler

React DevTools sada prikazuje detaljne informacije specifične za Fabric renderiranje:

  • Commit faze — Koliko vremena Fabric treba za svaki commit ciklus
  • Layout izračuni — Vrijeme provedeno u Yoga engine-u za izračun rasporeda
  • Nativne operacije — Vizualizacija poziva prema nativnom sloju kroz JSI

Migracija na novu arhitekturu: Praktični vodič

Ako imate postojeći React Native projekt koji još koristi staru arhitekturu, evo detaljnog vodiča za migraciju. Nemojte paničariti — proces je postepan i (uglavnom) bezbolan.

Korak 1: Revizija ovisnosti

Prije svega, provjerite kompatibilnost svih biblioteka koje koristite:

# Generirajte popis ovisnosti
npx react-native info

# Provjerite kompatibilnost na React Native Directory
# https://reactnative.directory/?newArchitecture=true

# Za Expo projekte
npx expo install --check

Više od 850 biblioteka već je kompatibilno s novom arhitekturom, uključujući sve one s više od 200.000 tjednih preuzimanja. No, ako koristite neku nišnu biblioteku, svakako provjerite njezinu kompatibilnost prije nego krenete dalje.

Korak 2: Nadogradnja React Native verzije

# Za Expo projekte
npx expo install expo@latest
npx expo install --fix

# Za bare React Native projekte
npx react-native upgrade

Korak 3: Omogućavanje Hermesa

Hermes je obavezan za novu arhitekturu. Provjerite da je uključen:

// app.json (Expo)
{
  "expo": {
    "jsEngine": "hermes"
  }
}

// android/gradle.properties (bare RN)
hermesEnabled=true

Korak 4: Omogućavanje nove arhitekture

// app.json (Expo)
{
  "expo": {
    "newArchEnabled": true
  }
}

// android/gradle.properties (bare RN)
newArchEnabled=true

// ios/Podfile (bare RN)
ENV['RCT_NEW_ARCH_ENABLED'] = '1'

Korak 5: Migracija prilagođenih nativnih modula

Ako imate vlastite nativne module, trebat ćete ih migrirati na TurboModules. Evo kako taj postupak izgleda:

  1. Kreirajte TypeScript specifikaciju za svaki modul
  2. Konfigurirajte Codegen u package.json
  3. Ažurirajte nativni kod za korištenje TurboModule API-ja
  4. Testirajte s novom arhitekturom omogućenom

Korak 6: Testiranje i profiliranje

# Pokrenite aplikaciju s novom arhitekturom
npx expo run:ios   # ili run:android

# Provjerite logove za eventualna upozorenja
# o nekompatibilnim modulima

# Profilirajte performanse
npx react-native-performance-profiler

Česti problemi pri migraciji i rješenja

Evo najčešćih problema na koje ćete vjerojatno naići (i kako ih riješiti):

  • "TurboModule not found" — Provjerite imenovanje specifikacijske datoteke (mora biti Native*.ts) i konfiguraciju Codegen-a
  • Crash pri pokretanju — Najčešće je kriva nekompatibilna biblioteka. Provjerite logove, pa ažurirajte ili zamijenite problematičnu biblioteku
  • Vizualne nekonzistentnosti — Fabric može drugačije renderirati neke komponente. Testirajte na obje platforme
  • TypeScript greške u Codegen-u — Codegen zahtijeva stroge tipske definicije. Koristite strict: true u tsconfig.json

Expo SDK 55 i nova arhitektura

Expo SDK 55, objavljen u siječnju 2026., predstavlja pravu prekretnicu — to je prva verzija koja isključivo koristi novu arhitekturu i nema povratka na staru. SDK 55 dolazi s React Native 0.83.1 i React 19.2.0.

Nove značajke u SDK 55

  • Apple Zoom tranzicije — Podrška za interaktivne tranzicije dijeljenih elemenata na iOS-u koristeći nativne zoom geste
  • Stack.Toolbar API — Novi API za UIToolbar na iOS-u koji pruža pristup za izgradnju izbornika i akcija
  • SplitView eksperimentalna podrška — Dugo očekivana podrška za podijeljene poglede na tabletima (konačno!)
  • expo-brownfield paket — Omogućuje pakiranje React Native koda kao nativne biblioteke (AAR za Android, XCFramework za iOS) koju nativni developeri mogu koristiti bez postavljanja Node.js-a
// Primjer korištenja Apple Zoom tranzicije
import { Stack } from 'expo-router';

export default function Layout() {
  return (
    <Stack
      screenOptions={{
        animation: 'zoom', // Nova zoom tranzicija
      }}
    >
      <Stack.Screen name="index" />
      <Stack.Screen name="details" />
    </Stack>
  );
}

// Primjer Stack.Toolbar API-ja
import { Stack } from 'expo-router';

export default function DetailsScreen() {
  return (
    <>
      <Stack.Screen
        options={{
          title: 'Detalji',
        }}
      />
      <Stack.Toolbar>
        <Stack.Toolbar.Button
          title="Uredi"
          onPress={() => console.log('Uređivanje')}
        />
        <Stack.Toolbar.Button
          title="Dijeli"
          onPress={() => console.log('Dijeljenje')}
        />
      </Stack.Toolbar>
    </>
  );
}

Usporedba performansi: Stara vs. nova arhitektura

Evo konkretnih brojki iz stvarnih testiranja. Ovi podaci govore sami za sebe:

Metrika Stara arhitektura Nova arhitektura Poboljšanje
Vrijeme pokretanja (TTI) ~2.5s ~1.3s ~48%
Memorijsko korištenje ~180MB ~150MB ~17%
FPS tijekom animacija ~45-55 FPS ~58-60 FPS ~15-30%
Veličina JS snopa Referentna ~10% manja ~10%
Nativni pozivi (latencija) ~5-10ms <1ms ~90%

Brojke mogu varirati ovisno o složenosti aplikacije, ali trend je neporeciv — nova arhitektura donosi poboljšanja u svim ključnim metrikama.

Najbolje prakse za novu arhitekturu

Na temelju iskustava timova koji su već prošli kroz migraciju, evo što bismo preporučili:

  1. Započnite s Expo-om — Expo značajno pojednostavljuje korištenje nove arhitekture automatiziranjem konfiguracije i pružanjem kompatibilnih biblioteka
  2. Koristite stroge TypeScript tipove — Codegen ovisi o preciznim tipskim definicijama. Omogućite strict mod u TypeScript konfiguraciji
  3. Profilirajte redovito — Koristite Performance Tracing i React DevTools za identificiranje uskih grla
  4. Migrirajte postupno — Ne pokušavajte sve migrirati odjednom. Interop layer omogućuje postupnu migraciju i to je OK
  5. Testirajte na stvarnim uređajima — Emulatori ne prikazuju uvijek realno ponašanje, posebno kad je riječ o performansama
  6. Pratite kompatibilnost biblioteka — Redovito provjeravajte React Native Directory za ažuriranja

Interop Layer: Most između starog i novog

Jedan od najvažnijih aspekata migracije je Interop Layer — sloj kompatibilnosti koji vam omogućuje postupnu migraciju bez potrebe da sve ažurirate odjednom. I moram reći, ovo je možda najmudrija odluka koju je Meta donijela u cijelom procesu.

Kako funkcionira Interop Layer

Interop Layer automatski omotava stare NativeModules i UIManager komponente tako da ih Fabric i TurboModules sustavi mogu koristiti. To u praksi znači da možete omogućiti novu arhitekturu čak i ako neke od vaših biblioteka još koriste stari API.

// Primjer: Stari modul koji radi kroz Interop Layer
// Ovaj kod nastavlja raditi bez izmjena
import { NativeModules } from 'react-native';
const { LegacyAnalytics } = NativeModules;

// Interop Layer automatski preusmjerava pozive
// kroz JSI umjesto kroz stari most
LegacyAnalytics.trackEvent('screen_view', {
  screen: 'HomeScreen',
  timestamp: Date.now(),
});

// Preporučeni pristup: Migracija na TurboModule
// specs/NativeAnalytics.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';

export interface Spec extends TurboModule {
  trackEvent(name: string, params: Object): void;
  setUserId(id: string): void;
  flush(): Promise<boolean>;
}

export default TurboModuleRegistry.getEnforcing<Spec>(
  'NativeAnalytics'
);

Ograničenja Interop Layera

Iako je Interop Layer iznimno koristan, treba biti svjestan njegovih ograničenja:

  • Performanse — Moduli koji rade kroz Interop Layer ne dobivaju pune prednosti nove arhitekture. Pozivi se i dalje moraju prevoditi između starog i novog API-ja, pa tu ima nešto overhead-a
  • Sinkroni pozivi — Stari NativeModules ne podržavaju sinkrone pozive, pa ta mogućnost nije dostupna dok se modul ne migrira na TurboModules
  • Deprecation — Interop Layer je privremeno rješenje. Meta planira postupno uklanjati podršku za stari API u budućim verzijama
  • Debugiranje — Greške u modulima koji rade kroz Interop Layer mogu biti nešto teže za dijagnostiku jer prolaze kroz dodatni sloj apstrakcije

Debugiranje u novoj arhitekturi

Nova arhitektura donosi poboljšane alate za debugiranje, ali i neke specifičnosti kojih treba biti svjestan.

React Native DevTools

React Native 0.83 uključuje značajna poboljšanja DevTools-a specifična za novu arhitekturu:

  • Network Inspector — Praćenje mrežnih zahtjeva izravno u DevTools-u, uključujući WebSocket komunikaciju i GraphQL upite
  • Component Inspector — Poboljšani inspektor koji prikazuje Fabric-specifične informacije poput commit faza i layout kalkulacija
  • Performance Timeline — Integrirana vremenska crta koja prikazuje JavaScript izvršavanje, React performanse, mrežne događaje i korisnička mjerenja u jednom prikazu
// Korištenje prilagođenih User Timings za debugiranje
performance.mark('fetchStart');

const response = await fetch('https://api.example.com/data');
const data = await response.json();

performance.mark('fetchEnd');
performance.measure('API poziv', 'fetchStart', 'fetchEnd');

// Ove oznake su vidljive u Performance Timeline
// unutar React Native DevTools-a

Flipper i nova arhitektura

Flipper, nekad popularni alat za debugiranje React Native aplikacija, od SDK 55 više nije uključen po zadanim postavkama. React Native DevTools preuzimaju većinu njegovih funkcionalnosti. No, Flipper se i dalje može ručno integrirati za naprednije scenarije:

# Instalacija Flipper podrške (opcionalno)
npx expo install react-native-flipper

# Pokretanje s Flipper podrškom
FLIPPER_ENABLED=1 npx expo run:ios

Česti problemi i rješenja pri debugiranju

Evo praktičnih savjeta za najčešće probleme:

  1. Module not found greške — Obično su uzrokovane neispravnim imenovanjem specifikacijskih datoteka. Codegen traži datoteke koje prate uzorak Native*.ts ili Native*.tsx, pa to obavezno provjerite
  2. Tipske greške u Codegen-u — Provjerite da koristite podržane tipove. Codegen ne podržava sve TypeScript tipove — generički tipovi i unija tipovi imaju ograničenu podršku
  3. Pad performansi pri migraciji — Ako primijetite pad performansi nakon migracije, provjerite rade li neki moduli kroz Interop Layer. Njihova potpuna migracija bi trebala riješiti problem
  4. Nativne pogreške bez jasnog stack trace-a — Koristite adb logcat na Androidu i Xcode konzolu na iOS-u za detaljnije nativne logove

Praktični primjer: Izrada kompletnog TurboModula za dijeljenje sadržaja

Za kraj, prođimo kroz izradu kompletnog TurboModula za dijeljenje sadržaja koji koristi nativne API-je obje platforme. Ovaj primjer lijepo demonstrira cijeli tijek rada od specifikacije do gotove komponente.

// specs/NativeShareModule.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';

export interface Spec extends TurboModule {
  shareText(text: string, title?: string): Promise<boolean>;
  shareUrl(url: string, title?: string): Promise<boolean>;
  shareImage(
    imageUri: string,
    message?: string
  ): Promise<boolean>;
  canShare(): boolean;
}

export default TurboModuleRegistry.getEnforcing<Spec>(
  'NativeShareModule'
);

A onda implementiramo React komponentu koja koristi taj modul:

// components/ShareButton.tsx
import React, { useCallback } from 'react';
import {
  TouchableOpacity,
  Text,
  Alert,
  StyleSheet,
} from 'react-native';
import NativeShareModule from '../specs/NativeShareModule';

interface ShareButtonProps {
  content: string;
  type: 'text' | 'url' | 'image';
  title?: string;
}

export function ShareButton({
  content,
  type,
  title,
}: ShareButtonProps) {
  const handleShare = useCallback(async () => {
    // Sinkrona provjera mogućnosti dijeljenja
    if (!NativeShareModule.canShare()) {
      Alert.alert(
        'Greška',
        'Dijeljenje nije dostupno na ovom uređaju'
      );
      return;
    }

    try {
      let success = false;

      switch (type) {
        case 'text':
          success = await NativeShareModule.shareText(
            content,
            title
          );
          break;
        case 'url':
          success = await NativeShareModule.shareUrl(
            content,
            title
          );
          break;
        case 'image':
          success = await NativeShareModule.shareImage(
            content,
            title
          );
          break;
      }

      if (success) {
        console.log('Sadržaj uspješno podijeljen');
      }
    } catch (error) {
      Alert.alert(
        'Greška',
        'Nije moguće podijeliti sadržaj'
      );
    }
  }, [content, type, title]);

  return (
    <TouchableOpacity
      style={styles.button}
      onPress={handleShare}
    >
      <Text style={styles.text}>Podijeli</Text>
    </TouchableOpacity>
  );
}

const styles = StyleSheet.create({
  button: {
    backgroundColor: '#007AFF',
    paddingHorizontal: 20,
    paddingVertical: 12,
    borderRadius: 8,
    alignItems: 'center',
  },
  text: {
    color: '#FFFFFF',
    fontSize: 16,
    fontWeight: '600',
  },
});

Ovaj primjer demonstrira ključne prednosti TurboModula: tipsku sigurnost (TypeScript specifikacija jamči ispravne tipove na obje strane), sinkrone pozive (canShare() se izvršava sinkrono), i asinkrone operacije (shareText() vraća Promise). I sve to bez serijalizacije podataka u JSON i slanja preko starog mosta.

Pogled u budućnost

Nova arhitektura React Nativea nije samo tehnička nadogradnja — ona je temelj za budućnost cross-platform mobilnog razvoja. S potpunom eliminacijom mosta, izravnom komunikacijom putem JSI-ja i podrškom za moderne React značajke, React Native se pozicionirao kao ozbiljna alternativa nativnom razvoju čak i za najzahtjevnije aplikacije.

U nadolazećim mjesecima možemo očekivati daljnja poboljšanja Hermes enginea, širu podršku za Concurrent React uzorke, naprednije alate za profiliranje, te još bolju integraciju s nativnim API-jima obje platforme.

S obzirom na to da je 83% Expo projekata već na novoj arhitekturi, smjer je jasan.

Ako još niste migrirali svoj projekt — sada je zapravo idealno vrijeme za početak. Alati su zreli, dokumentacija je opsežna, zajednica je aktivna. Vaši korisnici (i vaše metrike performansi) će vam biti zahvalni.

O Autoru Editorial Team

Our team of expert writers and editors.