Threads in React Native
Threads in React Native
~9 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Anders als eine reine Web-App läuft eine React-Native-App über MEHRERE Threads verteilt – wer versteht, welcher Code auf welchem Thread läuft, versteht auch, warum manche Animationen ruckeln und andere nicht (siehe Kapitel "Ein-/Ausblenden-Animation").
1. Beschreibung
Die klassische (Bridge-)Architektur unterscheidet drei Haupt-Threads: der JS-THREAD führt Ihren React-/JavaScript-Code aus (EIN einzelner Thread, kein Multithreading innerhalb von JS!), der NATIVE/UI-THREAD zeichnet die eigentlichen nativen Views (Android: Main-Thread, iOS: Main-Thread), der SHADOW-THREAD berechnet das Flexbox-Layout (Yoga-Engine) im Hintergrund. Die neuere JSI-Architektur (siehe Kapitel "Bridging") reduziert die Trennschärfe, das Grundprinzip bleibt aber bestehen.
2. Kurzes Beispiel
// Blockiert den JS-Thread für 3 Sekunden -
// alle Touch-Events UND State-Updates verzögern sich währenddessen:
function blockiereJsThread() {
const ende = Date.now() + 3000;
while (Date.now() < ende) {} // absichtlich schlechtes Beispiel!
}3. Komplettes Projekt: Reaktionsfähigkeits-Demo
npx create-expo-app threads-demo
cd threads-demoimport { useRef, useState } from 'react';
import { View, Text, Button, Animated, StyleSheet } from 'react-native';
export default function App() {
const [zaehler, setZaehler] = useState(0);
const drehung = useRef(new Animated.Value(0)).current;
// Läuft, solange die Komponente existiert - auf dem NATIVE-Thread dank useNativeDriver
function starteRotation() {
drehung.setValue(0);
Animated.loop(
Animated.timing(drehung, {
toValue: 1,
duration: 1500,
useNativeDriver: true,
})
).start();
}
// Blockiert absichtlich den JS-Thread
function blockiereJsThread() {
const ende = Date.now() + 2000;
while (Date.now() < ende) {}
}
const rotationStil = {
transform: [{
rotate: drehung.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] }),
}],
};
return (
<View style={styles.container}>
<Animated.View style={[styles.box, rotationStil]} />
<Text style={styles.zaehlerText}>Zähler: {zaehler}</Text>
<Button title="Rotation starten (native Animation)" onPress={starteRotation} />
<View style={styles.abstand}>
<Button title="Zähler erhöhen (JS-Thread)" onPress={() => setZaehler((z) => z + 1)} />
</View>
<View style={styles.abstand}>
<Button title="JS-Thread 2s blockieren" onPress={blockiereJsThread} color="#dc2626" />
</View>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, alignItems: 'center', paddingTop: 80 },
box: { width: 60, height: 60, backgroundColor: '#2563eb', marginBottom: 24 },
zaehlerText: { fontSize: 18, marginBottom: 24 },
abstand: { marginTop: 12 },
});4. Erklärung
- "Rotation starten" nutzt
useNativeDriver: true– die Animation läuft komplett auf dem NATIVE-Thread; sie dreht sich WEITER, auch während "JS-Thread 2s blockieren" gedrückt wird. - "Zähler erhöhen" läuft dagegen auf dem JS-Thread – während der 2-Sekunden-Blockade REAGIERT der Button nicht, weil die JS-Event-Schleife blockiert ist und das
onPress-Event erst danach verarbeitet werden kann. - Genau dieser Unterschied erklärt, warum
useNativeDriver: trueso wichtig ist: Animationen sollen flüssig bleiben, selbst wenn der JS-Thread durch teure Berechnungen (Netzwerk-Parsing, komplexe State-Updates) beschäftigt ist. - Für ECHTE rechenintensive Arbeit (Bildverarbeitung, komplexe Algorithmen) gibt es zusätzlich Bibliotheken wie
react-native-worklets-core, die Code auf einem eigenen, separaten Thread ausführen – über den Rahmen dieses Themas hinausgehend.