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ä,
recyclingKeyestää 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) jaopacityovat nopeita. Vältä layout-ominaisuuksia kutenwidth,height,margintaipadding— 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:ä jaSuspense: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ä:
- Mittaa ensin: Käytä profilointityökaluja ongelmien tunnistamiseen ennen kuin alat optimoimaan mitään
- Ota React Compiler käyttöön: Expo SDK 54+ -projekteissa se on oletuksena — vanhemmissa projekteissa lisää se Babel-pluginina
- Vaihda FlashList:iin tai Legend List:iin: FlatList on riittävä pienissä listoissa, mutta tuotantosovelluksissa modernit vaihtoehdot ovat selkeästi parempia
- Optimoi kuvat: Käytä expo-image:a, oikeita kuvakokoja ja CDN-palveluita
- Animoi oikein: Käytä Reanimated v4:ää ja animoi vain transform- sekä opacity-ominaisuuksia
- Navigoi natiivisti: Käytä native-stack-navigaattoria ja freezeOnBlur-asetusta
- 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.