Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Bilder-Performance mit expo-image in React Native

Bilder-Performance mit expo-image

~13 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026

ProductCards <Image source={{{{ uri: imageUrl }}}}> aus "React Native für Einsteiger" nutzt React Natives eingebaute Image-Komponente – funktional korrekt, aber ohne Caching-Kontrolle und ohne moderne Bildformat-Unterstützung. expo-image ersetzt sie mit deutlich mehr Performance-Funktionen.

expo-image installieren

npx expo install expo-image

ProductCard.js: Image durch expo-image ersetzen

components/ProductCard.js
import { memo } from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import { Image } from 'expo-image';

const BLURHASH = '|rF?hV%2WCj[ayj[a|j[az_NaeWBj@ayfRayfQfQM{M|azj[azf6fQfQfQIpWXofj[ayj[j[fQayWCoeoeaya}j[ayfQa{oLj?j[WVj[ayayj[fQoff7azayj[ayj[j[ayofayayayj[fQj[ayayj[ayfjj[j[ayjuayj[';

function ProductCard({ name, price, imageUrl, onPress, isFavorite, onToggleFavorite }) {
  return (
    <TouchableOpacity style={styles.card} onPress={onPress}>
      <Image
        source={imageUrl}
        style={styles.image}
        placeholder={{ blurhash: BLURHASH }}
        contentFit="cover"
        transition={200}
        cachePolicy="memory-disk"
      />
      <View style={styles.info}>
        <Text style={styles.name}>{name}</Text>
        <Text style={styles.price}>${price.toFixed(2)}</Text>
      </View>
      <TouchableOpacity style={styles.favoriteButton} onPress={onToggleFavorite}>
        <Text style={styles.favoriteIcon}>{isFavorite ? '♥' : '♡'}</Text>
      </TouchableOpacity>
    </TouchableOpacity>
  );
}

const styles = StyleSheet.create({
  card: {
    flexDirection: 'row',
    padding: 12,
    marginBottom: 8,
    backgroundColor: '#f9fafb',
    borderRadius: 8,
    alignItems: 'center',
  },
  image: { width: 60, height: 60, borderRadius: 4 },
  info: { marginLeft: 12, flex: 1 },
  name: { fontSize: 16, fontWeight: '600' },
  price: { fontSize: 14, color: '#6b7280' },
  favoriteButton: { padding: 8 },
  favoriteIcon: { fontSize: 20, color: '#ef4444' },
});

export default memo(ProductCard);

Die wichtigsten neuen Props im Detail

  • source={{imageUrl}} statt source={{{{ uri: imageUrl }}}}expo-image akzeptiert einen einfachen URL-String direkt, das uri-Objekt-Wrapping der eingebauten Image-Komponente entfällt.
  • placeholder={{{{ blurhash: BLURHASH }}}} – zeigt einen unscharfen Platzhalter (aus einem kompakten Text-String generiert, siehe blurha.sh zum Erzeugen eigener Werte) WÄHREND das echte Bild lädt, statt eines leeren grauen Rechtecks.
  • contentFit="cover" – das direkte Äquivalent zu CSS' object-fit bzw. der eingebauten Image-Komponente resizeMode-Prop (siehe "React Native Referenz", Thema "Hintergrundbild"), nur mit klarerer Namensgebung.
  • transition={{200}} – sanftes Einblenden (200ms) statt abruptem Erscheinen, sobald das Bild fertig geladen ist.
  • cachePolicy="memory-disk" – DER entscheidende Performance-Unterschied zur eingebauten Image-Komponente, siehe nächster Abschnitt.

cachePolicy im Detail: warum das wichtig ist

React Natives eingebaute Image-Komponente cached Bilder NUR unzuverlässig/plattformabhängig – ein Produkt, das man mehrfach besucht (Produktliste → Detail → zurück → erneut Detail), lädt sein Bild oft MEHRFACH neu über das Netzwerk. cachePolicy="memory-disk" aktiviert ZWEI Cache-Ebenen:

  • Memory-Cache: bereits dekodierte Bilder bleiben im Arbeitsspeicher – SOFORTIGE Anzeige beim erneuten Rendern derselben Bild-URL innerhalb derselben App-Sitzung.
  • Disk-Cache: heruntergeladene Bilddaten bleiben auf dem Gerät gespeichert – kein erneuter Netzwerk-Download nötig, selbst nach einem App-Neustart, solange der Cache nicht geleert wurde.

Bonus: Bilder vorab laden mit Image.prefetch

Für ein noch flüssigeres Erlebnis kann man Bilder BEVOR sie sichtbar werden vorladen – z. B. direkt nach dem Laden der Produktliste in ProductListScreen:

import { Image } from 'expo-image';

// Nach dem erfolgreichen fetchProducts()-Aufruf:
Image.prefetch(items.map((product) => product.imageUrl));

Wenn der Nutzer dann tatsächlich scrollt, sind die Bilder oft schon im Disk-Cache – die FlatList muss nicht mehr auf den Netzwerk-Download warten, nur noch auf die (sehr schnelle) Cache-Lese-Operation.

Tipp: Faustregel für Bilder-Performance: expo-image mit cachePolicy="memory-disk" ist praktisch IMMER die richtige Wahl gegenüber der eingebauten Image-Komponente, sobald eine App mehr als ein oder zwei Bilder zeigt – die Umstellung kostet wenig Aufwand (meist nur Import-Tausch + Props umbenennen), der Performance-Gewinn bei wiederholt angezeigten Bildern (wie unseren Produktbildern) ist erheblich.