React Native -suorituskyvyn optimointi 2026: FlashList, React Compiler ja käytännön tekniikat

Opi optimoimaan React Native -sovelluksesi suorituskyky vuonna 2026. Opas kattaa FlashList v2:n näkymien kierrätyksen, React Compilerin automaattisen memoisaation, Reanimated v4:n CSS-animaatiot ja profilointityökalut käytännön esimerkein.

Johdanto: suorituskyky ratkaisee kaiken

Puhutaan suoraan. Suorituskyky ei ole mikään "kiva bonus" — se on mobiilisovelluksen elinehto. Käyttäjät odottavat 60 FPS:n sulavuutta, välittömiä vasteaikoja ja sujuvaa vieritystä. Jos sovellus nykii tai lataa hitaasti, käyttäjät katoavat sovelluskaupan arvioihin kirjoittamaan yhden tähden palautetta.

Tuttu juttu, eikö vain?

React Native on kuitenkin kehittynyt valtavasti suorituskykyrintamalla vuonna 2026. Uusi arkkitehtuuri (JSI, Fabric, TurboModules) on nyt oletuksena, React Compiler 1.0 automatisoi memoisaation, FlashList v2 mullistaa listarenderöinnin ja Reanimated v4 tuo CSS-animaatiot React Nativeen. Mutta — ja tämä on iso mutta — näiden työkalujen tehokas hyödyntäminen vaatii ymmärrystä siitä, missä suorituskykyongelmat oikeasti syntyvät ja miten ne ratkaistaan.

Tässä oppaassa käymme läpi React Native -sovellusten suorituskyvyn optimoinnin kattavasti: turhien uudelleenrenderöintien välttämisestä listaoptimoinnin kautta animaatioihin ja profilointiin. Jokainen osio sisältää käytännön koodiesimerkkejä, joita voit soveltaa suoraan omissa projekteissasi.

Turhien uudelleenrenderöintien välttäminen

Uudelleenrenderöinti on yleisin suorituskykyongelmien lähde React Native -sovelluksissa. Joka kerta kun komponentin tila tai propsit muuttuvat, React joutuu vertaamaan virtuaalista DOM-puuta ja päivittämään natiivit näkymät. Monimutkaisissa komponenttipuissa tämä prosessi voi olla yllättävänkin raskas.

React.memo: estä turhat renderöinnit

React.memo on ensimmäinen puolustuslinja turhia uudelleenrenderöintejä vastaan. Kyseessä on higher-order-komponentti, joka vertaa propseja pinnallisesti (shallow comparison) ja ohittaa renderöinnin, jos mikään ei ole muuttunut. Yksinkertaista ja tehokasta.

// components/ProductCard.tsx
import React from 'react';
import { View, Text, Image, StyleSheet } from 'react-native';

interface ProductCardProps {
  id: string;
  name: string;
  price: number;
  imageUrl: string;
}

// Ilman React.memo tämä renderöityy aina kun parent renderöityy
// React.memo estää turhan renderöinnin kun propsit eivät muutu
const ProductCard = React.memo<ProductCardProps>(({
  name, price, imageUrl
}) => {
  console.log('ProductCard renderöityi:', name);

  return (
    <View style={styles.card}>
      <Image source={{ uri: imageUrl }} style={styles.image} />
      <Text style={styles.name}>{name}</Text>
      <Text style={styles.price}>{price.toFixed(2)} €</Text>
    </View>
  );
});

const styles = StyleSheet.create({
  card: {
    padding: 12,
    borderRadius: 8,
    backgroundColor: '#fff',
    marginBottom: 8,
  },
  image: { width: '100%', height: 150, borderRadius: 6 },
  name: { fontSize: 16, fontWeight: '600', marginTop: 8 },
  price: { fontSize: 14, color: '#666', marginTop: 4 },
});

export default ProductCard;

Tärkeä huomio: React.memo on täysin hyödytön, jos propsit muuttuvat joka renderöinnillä. Tämä on yllättävän yleinen virhe — jos välität inline-objekteja tai -funktioita propsina, luot uuden viitteen joka kerta. Ja silloin memoisaatio ei tee yhtään mitään.

useCallback ja useMemo: stabiloi viittaukset

useCallback estää funktioiden uudelleenluomisen joka renderöinnillä, ja useMemo välimuistittaa raskaat laskentatulokset. Yhdessä React.memo:n kanssa ne muodostavat tehokkaan optimointikokonaisuuden.

// screens/ProductListScreen.tsx
import React, { useCallback, useMemo, useState } from 'react';
import { View, TextInput, StyleSheet } from 'react-native';
import ProductCard from '../components/ProductCard';

export function ProductListScreen({ products }) {
  const [searchQuery, setSearchQuery] = useState('');
  const [sortBy, setSortBy] = useState('name');

  // useMemo: välimuistita suodatus- ja lajittelutulos
  // Lasketaan uudelleen vain kun products, searchQuery tai sortBy muuttuu
  const filteredProducts = useMemo(() => {
    const filtered = products.filter(p =>
      p.name.toLowerCase().includes(searchQuery.toLowerCase())
    );
    return filtered.sort((a, b) => {
      if (sortBy === 'price') return a.price - b.price;
      return a.name.localeCompare(b.name);
    });
  }, [products, searchQuery, sortBy]);

  // useCallback: estä funktion uudelleenluonti
  const handleProductPress = useCallback((productId: string) => {
    navigation.navigate('ProductDetail', { id: productId });
  }, [navigation]);

  return (
    <View style={styles.container}>
      <TextInput
        value={searchQuery}
        onChangeText={setSearchQuery}
        placeholder="Hae tuotteita..."
        style={styles.searchInput}
      />
      {filteredProducts.map(product => (
        <ProductCard
          key={product.id}
          id={product.id}
          name={product.name}
          price={product.price}
          imageUrl={product.imageUrl}
        />
      ))}
    </View>
  );
}

Muista kuitenkin, ettei memoisaatio ole ilmaista. Se vie muistia ja lisää koodin monimutkaisuutta. Käytä sitä vain kun komponentti renderöityy usein samoilla propseilla tai kun laskenta on aidosti raskas — ei kaikkialle "varmuuden vuoksi".

React Compiler 1.0: automaattinen memoisaatio

Tässä tulee vuoden 2026 ehkä merkittävin uutinen React Native -kehittäjille. React Compiler 1.0 julkaistiin vakaana versiona vuoden 2025 lopulla, ja se muuttaa perustavanlaatuisesti tapaa, jolla suorituskykyä optimoidaan.

Kyseessä on käännösaikana toimiva työkalu, joka lisää automaattisesti memoisaation komponentteihin ja hookeihin. Eli ne useMemo:t, useCallback:it ja React.memo:t, joita olet kirjoittanut käsin vuosikausia? Compilerin kanssa niitä ei enää tarvita.

Miten React Compiler toimii?

React Compiler analysoi koodisi käännösvaiheessa ja lisää optimoinnit automaattisesti. Se osaa jopa memoisoida arvoja ehdollisesti — mikä ei edes ole mahdollista manuaalisella memoisaatiolla. Metan tuotantokäytössä Compiler on saavuttanut 20–30 % vähennyksen renderöintiaikoihin ja viiveisiin, mikä on rehellisesti sanottuna todella vaikuttava lukema.

// Ennen: manuaalinen memoisaatio
import React, { useCallback, useMemo } from 'react';

function OrderSummary({ items, taxRate }) {
  const total = useMemo(() => {
    return items.reduce((sum, item) => sum + item.price * item.qty, 0);
  }, [items]);

  const totalWithTax = useMemo(() => {
    return total * (1 + taxRate);
  }, [total, taxRate]);

  const handleCheckout = useCallback(() => {
    processPayment(totalWithTax);
  }, [totalWithTax]);

  return (/* ... */);
}

export default React.memo(OrderSummary);

// Jälkeen: React Compiler hoitaa kaiken automaattisesti
function OrderSummary({ items, taxRate }) {
  const total = items.reduce(
    (sum, item) => sum + item.price * item.qty, 0
  );
  const totalWithTax = total * (1 + taxRate);

  const handleCheckout = () => {
    processPayment(totalWithTax);
  };

  return (/* ... */);
}

// Ei tarvita React.memo-käärettä, useMemo:a tai useCallback:ia!

React Compilerin käyttöönotto Expo-projektissa

Expo SDK 54:stä lähtien React Compiler on oletuksena käytössä uusissa projekteissa. Jos sinulla on olemassa oleva projekti, se onnistuu näin:

# Asenna React Compiler -plugin
npx expo install babel-plugin-react-compiler

# babel.config.js
module.exports = function (api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: [
      ['babel-plugin-react-compiler', {
        // Voit kohdistaa compilerin tiettyihin kansioihin
        // sources: (filename) => filename.includes('src/'),
      }],
    ],
  };
};

Varoventtiili: Jos Compiler aiheuttaa ongelmia yksittäisessä komponentissa, voit ohittaa sen "use no memo" -direktiivillä. Manuaalinen useMemo ja useCallback toimivat edelleen escape hatch -mekanismeina, kun tarvitset tarkkaa hallintaa.

Listaoptimointi: FlatList, FlashList ja Legend List

Listat ovat mobiilisovellusten yleisimpiä ja samalla vaativimpia komponentteja. Olipa kyseessä tuoteluettelo, uutissyöte tai chat-sovellus, listan renderöinnin tehokkuus vaikuttaa suoraan käyttökokemukseen.

Ja rehellisesti sanottuna, tämä on se kohta jossa monet React Native -sovellukset alkavat takkuilla.

FlatListin ongelma: mount/unmount-sykli

React Nativen sisäänrakennettu FlatList luo jokaisen listaelementin alusta lähtien, kun se tulee näkymään, ja poistaa sen kokonaan näytöltä häviessään. Vaikka olisit vierittänyt saman elementin ohi viisi kertaa, FlatList mounttaa uuden komponentin joka kerta. Tämä tekee React.memo:sta käytännössä hyödyttömän — komponentti ei koskaan "pysähdy", vaan se luodaan ja tuhotaan jatkuvasti.

Jos käytät edelleen FlatList:iä (ja moni käyttää), näillä asetuksilla saat siitä parhaan mahdollisen irti:

import { FlatList, StyleSheet } from 'react-native';

function OptimizedFlatList({ data }) {
  const renderItem = useCallback(({ item }) => (
    <ProductCard
      id={item.id}
      name={item.name}
      price={item.price}
      imageUrl={item.imageUrl}
    />
  ), []);

  const keyExtractor = useCallback(
    (item) => item.id.toString(),
    []
  );

  // getItemLayout ohittaa dynaamisen mittauksen
  // Käytä vain kun tiedät elementtien tarkan korkeuden
  const getItemLayout = useCallback((_, index) => ({
    length: ITEM_HEIGHT,
    offset: ITEM_HEIGHT * index,
    index,
  }), []);

  return (
    <FlatList
      data={data}
      renderItem={renderItem}
      keyExtractor={keyExtractor}
      getItemLayout={getItemLayout}
      // Renderöi aluksi vain 10 elementtiä
      initialNumToRender={10}
      // Renderöi 5 elementtiä kerrallaan vieritettäessä
      maxToRenderPerBatch={5}
      // Pienennä ikkunakokoa muistin säästämiseksi
      windowSize={5}
      // Poista leikatut näkymät (Android-optimointi)
      removeClippedSubviews={true}
    />
  );
}

FlashList v2: näkymien kierrätys mullistaa suorituskyvyn

FlashList on Shopifyn kehittämä listakomponentti, joka lainaa natiivilta käyttöjärjestelmiltä tutun konseptin: näkymien kierrätyksen (view recycling). Sen sijaan, että elementtejä tuhotaan ja luodaan uudelleen, FlashList käyttää samoja komponenttiinstansseja uudelleen eri datalla. Aivan kuten Androidin RecyclerView ja iOS:n UITableView toimivat.

FlashList v2 on kirjoitettu kokonaan uudelleen React Nativen uudelle arkkitehtuurille. Se ei enää vaadi elementtien kokoarvioita, tukee mukautuvaa renderöinti-ikkunaa ja toimii saumattomasti myös horisontaalisten listojen kanssa.

import { FlashList } from '@shopify/flash-list';

function ProductFeed({ products }) {
  const renderItem = useCallback(({ item }) => (
    <ProductCard
      id={item.id}
      name={item.name}
      price={item.price}
      imageUrl={item.imageUrl}
    />
  ), []);

  return (
    <FlashList
      data={products}
      renderItem={renderItem}
      // estimatedItemSize auttaa FlashListiä laskemaan
      // alustavan layout:n ennen mittausta
      estimatedItemSize={200}
      // getItemType parantaa kierrätystä eri tyyppisille
      // elementeille (esim. teksti vs. kuva)
      getItemType={(item) => {
        return item.hasImage ? 'with-image' : 'text-only';
      }}
      keyExtractor={(item) => item.id}
    />
  );
}

Ja nyt ne luvut, jotka puhuvat puolestaan: todellisissa testeissä FlashList on parantanut keskimääräistä FPS:ää 36,9:stä 56,9:ään (54 % parannus) ja vähentänyt CPU-käyttöä 198,9 prosentista 36,5 prosenttiin. Se on 82 % vähennys. Erityisesti edullisemmilla Android-laitteilla ero on kuin yö ja päivä.

Legend List: puhdas TypeScript-vaihtoehto

Legend List on kiinnostava uusi tulokas. Se on kirjoitettu puhtaasti TypeScriptillä ilman natiiviriippuvuuksia, mikä tekee integroinnista helppoa ja yhteensopivuudesta varmaa. Se tukee natiivisti vaihtelevia elementtikokoja ilman suorituskykyongelmia ja tarjoaa erikoisominaisuuksia kuten chat-käyttöliittymän tuen sekä kaksisuuntaisen äärettömän vierityksen.

import { LegendList } from '@legendapp/list';

function ChatScreen({ messages }) {
  return (
    <LegendList
      data={messages}
      renderItem={({ item }) => <ChatBubble message={item} />}
      keyExtractor={(item) => item.id}
      // Chat-optimoinnit
      alignItemsAtEnd={true}
      maintainScrollAtEnd={true}
      // Valinnainen: ota käyttöön näkymien kierrätys
      recycleItems={true}
      estimatedItemSize={80}
    />
  );
}

Minkä listakomponentin valitsen?

Tässä nopea päätöspuu:

  • FlatList: Pienet ja staattiset listat, alle 100 elementtiä. Riittää prototyyppeihin ja yksinkertaisiin näkymiin.
  • FlashList v2: Tuotantosovelluksen ensisijainen valinta. Paras suorituskyky suurilla datamäärillä näkymien kierrätyksellä. Vaatii uuden arkkitehtuurin.
  • Legend List: Chat-sovellukset, kaksisuuntainen ääretön vieritys, dynaamisesti vaihtelevat elementtikoot. Ei natiiviriippuvuuksia, joten integrointi on vaivatonta.

Kuvaoptimointi: expo-image ja oikeat käytännöt

Kuvat ovat usein suurin yksittäinen muistinkuluttaja mobiilisovelluksissa. Tämä on sellainen asia, jonka moni huomaa vasta kun sovellus alkaa kaatumaan muistiongelmien takia (omasta kokemuksesta puhuen). React Nativen sisäänrakennettu Image-komponentti ei tarjoa kunnollisia välimuistimekanismeja, joten tuotantosovelluksissa kannattaa ehdottomasti käyttää expo-image-kirjastoa.

import { Image } from 'expo-image';

const blurhash = '|rF?hV%2WCj[ayj[a|j[az';

function OptimizedImage({ uri, width, height }) {
  return (
    <Image
      source={{ uri }}
      style={{ width, height }}
      // Käytä blur hash -paikkamerkkiä latauksen aikana
      placeholder={{ blurhash }}
      // Välimuistita levylle
      cachePolicy="disk"
      // Skaalaa kuva automaattisesti oikeaan kokoon
      contentFit="cover"
      // Siirtymäanimaatio kun kuva latautuu
      transition={200}
      // Estä kuvan vilkkuminen listoissa kierrätyksen aikana
      recyclingKey={uri}
    />
  );
}

Tärkeimmät kuvaoptimoinnin säännöt:

  • Älä lataa isompia kuvia kuin tarvitset. Jos käyttöliittymässä näytetään 200×200 pikselin thumbnail, 2000×2000 pikselin kuvan lataaminen tuhlaa kaistaa ja muistia. Ihan turhaan.
  • Käytä CDN:ää ja dynaamista skaalausta. Palvelinpuolen kuvanmuokkauspalvelut tuottavat oikean kokoisia kuvia automaattisesti.
  • Blur hash -paikkamerkit. Näytä kompakti blur hash -kuva latauksen aikana tyhjän tilan sijaan — se tekee käyttökokemuksesta huomattavasti ammattimaisemman.
  • recyclingKey listoissa. Kun käytät kuvia FlashListin tai Legend Listin sisällä, recyclingKey estää vanhan kuvan vilkkumisen kierrätyksen aikana.

Animaatiot: Reanimated v4 ja natiivit animaatiot

Huonosti toteutetut animaatiot ovat toiseksi yleisin syy sovelluksen nykimiseen. Ydinongelmana on se, että React Nativen sisäänrakennettu Animated-API laskee oletusarvoisesti jokaisen animaatiokehyksen JavaScript-säikeessä. Jos JS-säie on kiireinen vaikkapa datan käsittelyssä, animaatiot yksinkertaisesti pysähtyvät.

Se näyttää käyttäjälle todella huonolta.

Reanimated v4: CSS-animaatiot React Nativessa

React Native Reanimated v4 on julkaistu vakaana versiona vuonna 2026. Se toimii ainoastaan uudella arkkitehtuurilla ja tuo mukanaan CSS-pohjaisen animaatio-API:n — tutun standardin, joka tekee animaatioista deklaratiivisia ja helposti optimoitavia.

import Animated, {
  useAnimatedStyle,
  withSpring,
  withTiming,
  useSharedValue,
  // Uusi v4: CSS-animaatiot
  CSSAnimationKeyframes,
} from 'react-native-reanimated';

// Perinteinen Reanimated-animaatio (toimii v3 ja v4)
function AnimatedCard() {
  const scale = useSharedValue(1);

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ scale: withSpring(scale.value) }],
  }));

  const handlePressIn = () => { scale.value = 0.95; };
  const handlePressOut = () => { scale.value = 1; };

  return (
    <Animated.View
      style={[styles.card, animatedStyle]}
      onTouchStart={handlePressIn}
      onTouchEnd={handlePressOut}
    >
      {/* Sisältö */}
    </Animated.View>
  );
}

// Uusi v4: CSS-tyylinen animaatio
function FadeInView({ children }) {
  return (
    <Animated.View
      style={{
        animationName: CSSAnimationKeyframes({
          from: { opacity: 0, transform: [{ translateY: 20 }] },
          to: { opacity: 1, transform: [{ translateY: 0 }] },
        }),
        animationDuration: '0.4s',
        animationTimingFunction: 'ease-out',
        animationFillMode: 'forwards',
      }}
    >
      {children}
    </Animated.View>
  );
}

Animaation suorituskykyohjeet

  • Animoi vain GPU-ystävällisiä ominaisuuksia: transform (scale, translateX/Y, rotate) ja opacity ovat nopeita. Vältä layout-ominaisuuksia kuten width, height, margin tai padding — ne aiheuttavat layout-uudelleenlaskentaa.
  • Komponenttien enimmäismäärä: Nyrkkisääntönä enintään 100 animoitua komponenttia edullisilla Android-laitteilla ja noin 500 iOS:llä.
  • Raskaat animaatiot: Käytä react-native-skia:a yhdessä Reanimatedin kanssa monimutkaisiin visuaalisiin efekteihin. Canvas-pohjainen piirtäminen on huomattavasti tehokkaampaa kuin yksittäisten React-komponenttien animointi.
  • Kehitys- vs. tuotantoversio: Suorituskykyregressiot näkyvät usein vain dev-buildissa. Release-moodissa sekä Reanimated että React Native on optimoitu kääntäjäoptimoinnein — testaa siis aina myös tuotantobuildilla.

Navigoinnin suorituskyky

Navigointi on alue, jossa pienet valinnat voivat aiheuttaa yllättävän suuria suorituskykyeroja. React Navigation v7:n native-stack-navigaattori suorittaa siirtymäanimaatiot natiivin käyttöliittymäsäikeen puolella, mikä eliminoi JS-säikeen pullonkaulan kokonaan.

import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();

function AppNavigator() {
  return (
    <Stack.Navigator
      screenOptions={{
        // Natiivit animaatiot — ei JS-säikeen kuormitusta
        animation: 'slide_from_right',
        animationDuration: 200,
        // Ota käyttöön koko ruudun pyyhkäisyele
        gestureEnabled: true,
        fullScreenGestureEnabled: true,
        // Jäädytä edellinen näyttö siirtymän aikana
        freezeOnBlur: true,
      }}
    >
      <Stack.Screen name="Home" component={HomeScreen} />
      <Stack.Screen name="Detail" component={DetailScreen} />
    </Stack.Navigator>
  );
}

Muutama lisävinkki navigoinnin optimointiin:

  • Laiska lataus: Käytä React.lazy:ä ja Suspense:a raskaiden näyttöjen lataamiseen vasta kun niitä tarvitaan. Tämä nopeuttaa erityisesti sovelluksen käynnistystä.
  • freezeOnBlur: Jäädyttää taustalla olevat näytöt, jotta ne eivät kuluta resursseja turhaan.
  • useFocusEffect: Siivoa resurssit (WebSocket-yhteydet, ajastimet) kun näyttö menettää fokuksen. Muuten ne jäävät elämään taustalle ja syövät sekä muistia että suoritintehoa.

Profilointityökalut: mittaa ennen optimointia

Tässä on kultainen sääntö, jota ei voi korostaa liikaa: älä koskaan optimoi "mutu-tuntumalla".

Mittaa ensin. Optimoi sitten. Ja mittaa uudelleen. Vuonna 2026 React Native tarjoaa useita tehokkaita profilointityökaluja, joten tekosyitä mittaamattomuudelle ei oikeastaan ole.

React Native DevTools

React Native DevTools on React Native 0.76:sta lähtien ollut oletusvirheenkorjaustyökalu (korvasi Flipperin). Se tarjoaa tuttua Chrome DevTools -kokemusta: konsolilokien tarkastelun, breakpointit ja crash-pinojen analysoinnin. Käynnistä se painamalla Dev Menussa "Open DevTools" tai terminaalissa j-näppäintä.

React DevTools Profiler

Profiler-välilehti React DevToolsissa on korvaamaton työkalu turhien uudelleenrenderöintien jäljittämisessä. Se näyttää jokaisen renderöintisyklin: mitkä komponentit renderöityivät, miksi ne renderöityivät ja kuinka kauan se kesti. Suosittelen lämpimästi tutustumaan tähän, jos et ole sitä vielä tehnyt.

why-did-you-render

why-did-you-render on kätevä kirjasto, joka varoittaa automaattisesti turhista uudelleenrenderöinneistä kehityksen aikana. Se kertoo tarkalleen, mikä propsi tai tila muuttui ja miksi komponentti renderöityi uudelleen.

// wdyr.ts — tuo tämä ennen muita importteja
import React from 'react';

if (__DEV__) {
  const whyDidYouRender = require(
    '@welldone-software/why-did-you-render'
  );
  whyDidYouRender(React, {
    trackAllPureComponents: true,
    // Loggaa konsoliin
    logOnDifferentValues: true,
  });
}

Reactotron

Reactotron on ilmainen työpöytäsovellus, joka tarjoaa kattavan näkymän sovelluksen tilaan, verkkoliikenteeseen ja suorituskykyyn. Se integroituu Zustandin, Reduxin ja MMKV:n kanssa ja näyttää HTTP-pyyntöjen yksityiskohdat verkko-paneelissa. Erityisen hyödyllinen, kun haluat ymmärtää mitä sovelluksesi tekee "konepellin alla".

Alustakohtaiset työkalut

Älä unohda natiivia tasoa. Xcoden View Hierarchy Inspector ja Android Studion Layout Inspector paljastavat natiivin käyttöliittymäkerroksen ongelmat, joita JavaScript-puolen työkalut eivät yksinkertaisesti näe. Nämä ovat erityisen hyödyllisiä, kun epäilet ongelman olevan Fabric-renderöijässä tai natiiveissa komponenteissa.

Yhteenveto: suorituskyvyn optimoinnin tarkistuslista

Suorituskyvyn optimointi ei ole kertaluontoinen projekti — se on jatkuva prosessi. Tässä tiivistetty tarkistuslista, jonka voit pitää lähettyvillä:

  1. Mittaa ensin: Käytä profilointityökaluja ongelmien tunnistamiseen ennen kuin alat optimoimaan mitään
  2. Ota React Compiler käyttöön: Expo SDK 54+ -projekteissa se on oletuksena — vanhemmissa projekteissa lisää se Babel-pluginina
  3. Vaihda FlashList:iin tai Legend List:iin: FlatList on riittävä pienissä listoissa, mutta tuotantosovelluksissa modernit vaihtoehdot ovat selkeästi parempia
  4. Optimoi kuvat: Käytä expo-image:a, oikeita kuvakokoja ja CDN-palveluita
  5. Animoi oikein: Käytä Reanimated v4:ää ja animoi vain transform- sekä opacity-ominaisuuksia
  6. Navigoi natiivisti: Käytä native-stack-navigaattoria ja freezeOnBlur-asetusta
  7. Mittaa uudelleen: Varmista, että optimoinnit todella paransivat suorituskykyä — älä oleta

Usein kysytyt kysymykset

Tarvitaanko useMemo ja useCallback enää React Compilerin kanssa?

React Compiler 1.0 hoitaa memoisaation automaattisesti suurimmassa osassa tapauksia. Manuaalista useMemo:a ja useCallback:ia voi silti käyttää escape hatch -mekanismina tilanteissa, joissa tarvitaan tarkkaa hallintaa — esimerkiksi kun memoisoitu arvo on efektin riippuvuus. Uudessa koodissa suositus on kuitenkin luottaa Compileriin ja käyttää manuaalista memoisaatiota vain poikkeustapauksissa.

Kumpi on parempi: FlashList vai Legend List?

FlashList v2 on paras valinta suurimmalle osalle tuotantosovelluksia — se tarjoaa erinomaisen suorituskyvyn näkymien kierrätyksellä ja mukautuvalla renderöinti-ikkunalla. Legend List on parempi valinta chat-sovelluksiin, kaksisuuntaiseen äärettömään vieritykseen ja tilanteisiin, joissa natiiviriippuvuuksia halutaan välttää. Molemmat ovat FlatListin drop-in-korvauksia, joten kokeilu on helppoa.

Miten vähennän React Native -sovelluksen käynnistysaikaa?

Käynnistysajan optimoinnin tärkeimmät keinot ovat: Hermes-moottorin käyttö (oletuksena uusissa projekteissa), TurboModulesin laiska alustus, raskaiden näyttöjen laiska lataus React.lazy:llä, sovelluksen bundle-koon pienentäminen ja kolmansien osapuolien kirjastojen minimointi. Pienillä valinnoilla on kumulatiivinen vaikutus.

Toimiiko Reanimated v4 vanhan arkkitehtuurin kanssa?

Ei valitettavasti. Reanimated v4 vaatii React Nativen uuden arkkitehtuurin (Fabric + TurboModules). Jos sovelluksesi käyttää vielä vanhaa arkkitehtuuria, Reanimated v3 toimii ja sitä ylläpidetään edelleen aktiivisesti. Siirtyminen uuteen arkkitehtuuriin on kuitenkin suositeltavaa kaikille tuotantosovelluksille — ja se kannattaa tehdä mieluummin aikaisemmin kuin myöhemmin.

Miten löydän hitaimmat komponentit sovelluksestani?

Käytä React DevTools Profiler -välilehteä renderöintisyklien analysointiin — se näyttää jokaisen komponentin renderöintiajan ja syyn. Täydennä tätä why-did-you-render-kirjastolla, joka varoittaa turhista uudelleenrenderöinneistä automaattisesti. Natiivin tason ongelmiin Xcoden Instruments (iOS) ja Android Studion CPU Profiler ovat parhaita työkaluja.

Tietoa Kirjoittajasta Editorial Team

Our team of expert writers and editors.