Dieselbe Grafik-Engine wie Chrome und Flutter, direkt in der App
React Native Skia bindet Googles Skia-Grafik-Engine, dieselbe, die Chrome, Android und Flutter für 2D-Grafik nutzen, über JSI direkt in React Native ein. Statt Formen über native Views oder SVG-Elemente zu bauen, zeichnet Skia auf eine einzige native Surface, was individuelle Grafiken wie Signature Pads, Custom-Charts oder Bildfilter deutlich performanter macht als klassische View-basierte Ansätze.
Inhaltsverzeichnis
- 1. Was ist Skia und warum React Native Skia?
- 2. Das Canvas-Grundgerüst: Canvas, Group und Paint
- 3. Pfade zeichnen: Skia.Path für individuelle Formen
- 4. Praxisbeispiel: ein Signature Pad mit Touch-Events
- 5. Praxisbeispiel: ein performanter Custom-Chart
- 6. Skia-Werte mit Reanimated animieren
- 7. Wie Skia rendert: eigener Rendering-Pfad statt View-Hierarchie
- 8. Skia im Vergleich zu SVG-basierten Lösungen
- 9. Wann sich React Native Skia lohnt und wann nicht
- 10. Zusammenfassung
- 11. FAQ
1. Was ist Skia und warum React Native Skia?
Skia ist eine quelloffene 2D-Grafik-Engine von Google, die seit Jahren in Chrome, ChromeOS, Android selbst und seit einigen Versionen auch in Flutter zum Einsatz kommt. Sie stellt eine schnelle, plattformübergreifende Zeichen-API bereit, die Pfade, Text, Bilder und Shader auf eine Bitmap-Oberfläche rendert, unabhängig davon, ob darunter Metal auf iOS, OpenGL oder Vulkan auf Android liegt. React Native Skia, entwickelt von Shopify, bindet genau diese Engine über JSI in React Native ein und macht sie als deklarative React-Komponenten nutzbar.
Der entscheidende Unterschied zu klassischem React Native Rendering ist, dass Skia keine native View pro Element erzeugt. Ein Canvas mit hundert gezeichneten Kreisen bleibt eine einzige native Surface mit hundert Zeichenbefehlen, während eine View-basierte Lösung hundert eigene native Views mit jeweils eigenem Layout- und Rendering-Overhead erzeugen würde. Für individuelle, oft datengetriebene Grafiken ist das der Grund, warum Skia in der Praxis so viel schneller bleibt.
2. Das Canvas-Grundgerüst: Canvas, Group und Paint
Jede Skia-Zeichnung beginnt mit einer Canvas-Komponente, die einen festen Bereich der App als Zeichenfläche reserviert. Innerhalb des Canvas werden Primitive wie Circle, Rect, Path oder Text deklarativ als React-Kinder platziert, ähnlich wie man es von SVG-Bibliotheken kennt, nur dass am Ende alles auf dieselbe native Surface gezeichnet wird statt auf einzelne Views.
Optische Eigenschaften wie Farbe, Füllung, Strichbreite oder Transparenz werden über Paint-Objekte oder direkte Props wie color und style gesteuert. Mit Group lassen sich mehrere Primitive zusammenfassen und gemeinsam transformieren oder mit einem Shader überziehen, was für wiederverwendbare Grafik-Bausteine sehr praktisch ist.
import { Canvas, Circle, Path, Group } from '@shopify/react-native-skia';
function BasicShapes() {
return (
<Canvas style={{ width: 300, height: 300 }}>
<Group>
<Circle cx={150} cy={100} r={60} color="#4338ca" />
<Path
path="M 40 220 L 120 180 L 200 240 L 260 200"
color="#22d3ee"
style="stroke"
strokeWidth={4}
/>
</Group>
</Canvas>
);
}
3. Pfade zeichnen: Skia.Path für individuelle Formen
Für alles, was über einfache Kreise und Rechtecke hinausgeht, ist die imperative Path-API der zentrale Baustein. Über Skia.Path.Make() entsteht ein leeres Pfadobjekt, das anschließend mit Methoden wie moveTo, lineTo und cubicTo Schritt für Schritt aufgebaut wird, exakt wie bei der Canvas-2D-API im Browser, nur mit nativer Performance.
Dieses Pfadobjekt kann danach als path-Prop an eine Path-Komponente übergeben werden und lässt sich beliebig oft neu berechnen, etwa bei jedem Touch-Event eines Signature Pads oder bei jedem neuen Datenpunkt eines Charts. Weil die Pfadberechnung selbst reiner JavaScript- beziehungsweise Worklet-Code ist, lässt sie sich gut mit Reanimated kombinieren, worauf später in diesem Artikel noch eingegangen wird.
4. Praxisbeispiel: ein Signature Pad mit Touch-Events
Ein Signature Pad ist ein klassischer Anwendungsfall für Skia: Bei jedem Touch-Move-Event wird ein neuer Punkt an den aktuellen Pfad angehängt, wobei für eine weiche Linie meist quadTo statt einzelner lineTo-Segmente verwendet wird, um die Ecken zwischen den Punkten abzurunden. Der Pfad selbst lebt in einem Ref oder Shared Value, damit er nicht bei jedem Frame über React neu erzeugt werden muss.
Nach Abschluss der Unterschrift lässt sich das Ergebnis über makeImageSnapshot() direkt aus dem Canvas als Bild exportieren, zum Beispiel um es als Base64-String an ein Backend zu senden. Dieser Export passiert nativ und ohne einen Umweg über einen separaten Screenshot-Mechanismus, was Signature Pads mit Skia deutlich einfacher macht als früher üblich native Bridges dafür zu schreiben.
import { Canvas, Path, Skia, useCanvasRef } from '@shopify/react-native-skia';
import { GestureDetector, Gesture } from 'react-native-gesture-handler';
import { useState } from 'react';
function SignaturePad() {
const canvasRef = useCanvasRef();
const [path, setPath] = useState(() => Skia.Path.Make());
const pan = Gesture.Pan()
.onStart((e) => {
path.moveTo(e.x, e.y);
setPath(path.copy());
})
.onUpdate((e) => {
path.lineTo(e.x, e.y);
setPath(path.copy());
});
async function exportSignature() {
const image = canvasRef.current?.makeImageSnapshot();
const base64 = image?.encodeToBase64();
await uploadSignature(base64);
}
return (
<GestureDetector gesture={pan}>
<Canvas ref={canvasRef} style={{ width: 320, height: 200 }}>
<Path path={path} color="#111827" style="stroke" strokeWidth={3} />
</Canvas>
</GestureDetector>
);
}
5. Praxisbeispiel: ein performanter Custom-Chart
Für Charts mit vielen Datenpunkten zeigt sich der Vorteil von Skia besonders deutlich. Statt für jeden Datenpunkt eine eigene View oder ein eigenes SVG-Element zu erzeugen, wird der gesamte Linienzug als ein einziger Pfad aus den Datenwerten berechnet und in einem Zeichenbefehl an die native Surface übergeben. Bei mehreren hundert Punkten bleibt das Verhalten weiterhin flüssig, während View-basierte Ansätze hier oft spürbar ruckeln.
Zusätzlich lassen sich Füllflächen unter der Linie mit einem LinearGradient-Shader versehen, ohne zusätzliche Bibliotheken, weil Skia Shader als natives Konzept mitbringt. Das ergibt Charts, die optisch nah an nativen Analytics-Dashboards liegen, ohne dass dafür Bildmaterial oder komplexe SVG-Definitionen nötig wären.
function LineChart({ points }: { points: number[] }) {
const path = useMemo(() => {
const p = Skia.Path.Make();
points.forEach((value, i) => {
const x = i * (300 / (points.length - 1));
const y = 200 - value * 1.5;
i === 0 ? p.moveTo(x, y) : p.lineTo(x, y);
});
return p;
}, [points]);
return (
<Canvas style={{ width: 300, height: 200 }}>
<Path path={path} style="stroke" strokeWidth={2.5} color="#22d3ee">
<LinearGradient start={vec(0, 0)} end={vec(0, 200)} colors={['#4338ca', '#22d3ee']} />
</Path>
</Canvas>
);
}
6. Skia-Werte mit Reanimated animieren
React Native Skia ist von Grund auf für die Zusammenarbeit mit Reanimated gebaut. Statt Props wie Farbe, Radius oder Pfad über normalen React-State zu ändern, lassen sich Shared Values direkt als Werte an Skia-Komponenten übergeben, wodurch Änderungen ohne React-Re-Render und ohne den Umweg über den JS-Thread direkt auf dem UI-Thread neu gezeichnet werden.
Das erlaubt zum Beispiel eine Pfad-Interpolation, bei der zwischen zwei Formen weich übergeblendet wird, gesteuert durch einen einzigen Shared Value zwischen null und eins. Weil sowohl Reanimated als auch Skia auf demselben JSI-Fundament aufbauen, bleibt diese Kombination auch bei komplexen, datengetriebenen Animationen bei 60 Bildern pro Sekunde.
const progress = useSharedValue(0);
const animatedRadius = useDerivedValue(() => {
return interpolate(progress.value, [0, 1], [40, 90]);
});
<Canvas style={{ width: 200, height: 200 }}>
<Circle cx={100} cy={100} r={animatedRadius} color="#4338ca" />
</Canvas>
7. Wie Skia rendert: eigener Rendering-Pfad statt View-Hierarchie
Während normales React Native Rendering über die View-Hierarchie von Fabric läuft, mit Layout-Berechnung, Diffing und dem Erzeugen einzelner nativer Views, zeichnet Skia direkt auf eine GPU-gestützte Surface, ohne dass jedes Primitive eine eigene native Komponente wäre. Änderungen an einem Skia-Canvas lösen deshalb keinen React-Reconciliation-Durchlauf über hunderte Kindkomponenten aus, sondern nur einen neuen Zeichendurchlauf auf dem Canvas selbst.
Das macht Skia besonders geeignet für Szenarien mit vielen kleinen, sich häufig ändernden Elementen, etwa Partikel-Effekte, Waveform-Visualisierungen oder Echtzeit-Zeichnungen, bei denen eine View-basierte Lösung schlicht zu viele einzelne Layout-Passes bräuchte, um flüssig zu bleiben.
8. Skia im Vergleich zu SVG-basierten Lösungen
react-native-svg rendert jedes SVG-Element letztlich über eine eigene native View pro Knoten, was für statische oder wenig komplexe Illustrationen vollkommen ausreicht und den Vorteil hat, direkt mit vorhandenen SVG-Assets aus dem Design-Team zu arbeiten. Bei vielen Elementen oder häufigen Änderungen, etwa animierten Diagrammen, wird dieser View-pro-Element-Ansatz jedoch zum Flaschenhals.
Skia dagegen bringt eine steilere Lernkurve mit, weil Pfade und Transformationen oft imperativ statt rein deklarativ aufgebaut werden, und erhöht die native Binärgröße der App spürbar. Der Umstieg lohnt sich deshalb gezielt dort, wo Performance oder individuelle Zeichenlogik wichtiger sind als schnelle Einbindung fertiger Icons.
9. Wann sich React Native Skia lohnt und wann nicht
Für ein paar statische Icons oder eine einfache Illustration bleibt react-native-svg oder schlicht ein optimiertes PNG die einfachere und wartungsärmere Wahl. Skia zahlt sich dort aus, wo Grafiken interaktiv, datengetrieben oder animiert sind, etwa bei Signature Pads, Custom-Charts, Bildfiltern oder Zeichenwerkzeugen, bei denen View-basierte Ansätze an ihre Grenzen stoßen.
Ein guter Faustwert: Sobald mehr als ein Dutzend Grafikelemente gleichzeitig auf dem Bildschirm gezeichnet und regelmäßig neu berechnet werden müssen, lohnt sich der Blick auf Skia. Für alles darunter ist der zusätzliche Aufwand meist nicht gerechtfertigt.
| Anwendungsfall | Empfohlene Lösung | Warum | Aufwand |
|---|---|---|---|
| Ein paar statische Icons | react-native-svg oder PNG | Kein Rendering-Overhead nötig | Gering |
| Interaktives Signature Pad | React Native Skia | Direkter Pfad-Zugriff, hohe Frame-Rate | Mittel |
| Custom-Chart mit vielen Datenpunkten | React Native Skia | Ein Canvas-Zeichenbefehl statt hunderter Views | Mittel bis hoch |
| Bildfilter oder Foto-Editor | React Native Skia mit Shader | GPU-nahe Shader-Pipeline verfügbar | Hoch |
| Einfache Illustration ohne Interaktion | SVG oder Lottie | Deklarativ und wartungsärmer | Gering |
| Partikel-Effekt oder Waveform | React Native Skia | Viele Elemente ohne View-Overhead | Hoch |
Mironsoft
React-Native-App-Entwicklung und Magento-Anbindung
Eine mobile App zum Magento-Shop, die wirklich rund läuft?
Wir entwickeln React-Native-Apps, die sauber an die Magento REST- oder GraphQL-API angebunden sind, von der ersten Codezeile bis zur Veröffentlichung im App Store und bei Google Play.
App-Konzeption
Architektur und Feature-Umfang einer Magento-angebundenen App gemeinsam planen.
Magento-API-Integration
Produktkatalog, Warenkorb und Checkout sauber an die Shop-API anbinden.
Store-Veröffentlichung
App Store- und Google-Play-Freigabeprozess ohne Stolperfallen begleiten.
10. Zusammenfassung
React Native Skia
Kernidee
Skia zeichnet alle Primitive auf eine gemeinsame native Surface statt pro Element eine eigene View zu erzeugen.
Kern-API
Skia.Path.Make() baut individuelle Pfade imperativ auf, ähnlich der Canvas-2D-API im Browser.
Reanimated-Kombination
Shared Values können direkt als Skia-Props dienen und werden ohne React-Re-Render neu gezeichnet.
Einsatzregel
Ab etwa einem Dutzend gleichzeitiger, sich ändernder Grafikelemente lohnt sich der Umstieg von SVG auf Skia.