Wie Svelte Reaktivität, State-Management und Komponentenstruktur neu denkt.
SerieSvelte kompakt erklärt
Teil 2 von 8
Svelte hebt sich nicht nur durch seinen Compiler-Ansatz von anderen Frameworks ab, sondern auch durch seine schlanke und leistungsstarke Komponentenlogik. In diesem Teil der Serie steht die interne Funktionsweise im Fokus – insbesondere das Reaktivitätssystem, der Einsatz von Stores und wie Komponenten in größeren Anwendungen strukturiert werden.
Reaktivität – einfach, aber mächtig
Sveltes Reaktivität basiert nicht auf komplexen Proxy-Systemen oder Virtual DOMs, sondern auf simplen, kompilierbaren Signalen im Code. Sobald eine Variable in einer Komponente verändert wird, erkennt der Compiler die Abhängigkeit und generiert effizienten DOM-Code.
Beispiel: Reaktives Zählen
<script>
let count = 0;
function increment() {
count += 1;
}
</script>
<button on:click={increment}>Click: {count}</button>
Im Hintergrund wird beim Build ein Update-Code erzeugt, der den DOM direkt aktualisiert – ohne diffing oder Virtuelle DOM-Manipulation.
Reaktive Blöcke
Mit dem $:-Operator lassen sich reaktive Statements definieren:
let a = 2; let b = 3; $: sum = a + b;
Sobald a oder b geändert wird, wird sum automatisch neu berechnet. Das ermöglicht eine deklarative Programmierweise ohne zusätzliches State-Handling.
Stores – Zustand teilen zwischen Komponenten
Für globalen oder gemeinsam genutzten Zustand bietet Svelte Stores: reaktive Objekte mit einfacher API.
Typen von Stores:
- Writable: Lese-/Schreibbar
- Readable: Nur lesbar, z. B. abgeleitet vom Systemzustand
- Derived: Reaktiv berechnete Stores
Beispiel: Writable Store
// src/lib/stores/counter.js
import { writable } from 'svelte/store';
export const counter = writable(0);
Verwendung in einer Komponente:
<script>
import { counter } from '$lib/stores/counter.js';
</script>
<button on:click={() => counter.update((n) => n + 1)}> Increment </button>
<p>Counter: {$counter}</p>
Das $-Präfix bindet den Store automatisch in die Komponente ein und sorgt für Reaktivität.
Vorteil: Stores sind leichtgewichtig und brauchen kein Kontextsystem oder externe Bibliothek.
Komponenten-Architektur in Svelte-Projekten
Die empfohlene Struktur orientiert sich an der Trennung nach UI-Komponenten, Seiten, Logik, Stores und Stilen:
lib/components/enthält wiederverwendbare UI-Bausteine.routes/folgt der Datei-basierten Routingstruktur von SvelteKit.stores/hält globalen Zustand – ideal bei Login-Status, Themes, u. ä.
Slot-basierte Komponenten Svelte nutzt Slots für flexible Komponentenkomposition:
<div class="card">
<slot name="header" />
<slot />
<slot name="footer" />
</div>
Verwendung:
<Card>
<h2 slot="header">Titel</h2>
<p>Inhalt</p>
<small slot="footer">Fußzeile</small>
</Card>
Ein letzter Gedanke (Teil 3)
Sveltes Architektur zeigt, dass moderne Reaktivität nicht kompliziert sein muss. Die Kombination aus Compiler-gesteuerter Reaktivität, intuitivem Store-System und komponentenbasiertem Aufbau führt zu einem cleanen, wartbaren Code-Design – auch in größeren Projekten.
Im nächsten Teil der Reihe folgt ein Blick auf Animationen, Transitions, Actions und das Zusammenspiel mit der DOM-Welt – denn auch hier bietet Svelte clevere Lösungen, ganz ohne externe Bibliotheken.
Wann Sveltes Reaktivität an Grenzen stößt
Sveltes Reaktivität ist elegant — aber nicht überall überlegen. Aus realen Projekten:
- Bei tief verschachteltem State: Klassische
$:-Reaktivität funktioniert mit primitiven Werten und flachen Objekten gut. Bei tief verschachtelten Strukturen oder Listen mit hunderten Items wird der Compiler-Output groß und schwer zu debuggen. Hier sind Svelte 5 Runes oder explizites State-Management (mitwritableundderived) klarer. - Bei Server-Components-Patterns: React Server Components sind in Next.js etabliert; Svelte’s Server-Pendants (Server Routes,
+page.server.js) erfordern andere Patterns. Bei stark datengetriebenen Apps muss der State-Flow gut durchdacht sein, sonst verlieren sich Vorteile. - Bei Cross-Cutting-State (Auth, Theme, i18n): Stores sind gut, aber das Initialisierungs-Timing bei SSR ist tricky. Lösungen wie
getContext/setContextfunktionieren, brauchen aber konsistente Patterns im ganzen Codebase.
Svelte 5 (Runes) – wichtige Verschiebungen
Mit Svelte 5 ändert sich vieles, was Teil 3 als klassische Reaktivität beschreibt:
$state()ersetztletfür reaktive Werte: Explizitere Markierung, bessere TypeScript-Inferenz.$derived()ersetzt$:: Saubere Trennung zwischen Side-Effects ($effect) und Derived-Values.$props()für Komponenten-Props: Ersetztexport let.- Migration: Bestehender Svelte-4-Code läuft weiter (Backwards-kompatibel), aber neue Komponenten profitieren von Runes. Bei größeren Codebases ist die schrittweise Migration realistisch über 3–6 Monate.
Wo der “Compiler-Vorteil” überzeichnet ist
Svelte wird oft als “compiler-based, deshalb schneller” beworben. Das stimmt für Bundle-Größe und initiale Performance. Aber:
- Bei großen Apps verschiebt sich der Vorteil: React und Vue haben heute ähnliche Bundle-Optimierungen (Tree-Shaking, Code-Splitting). Bei sehr großen Anwendungen werden die Unterschiede kleiner.
- Runtime-Performance ist meist nicht der Engpass: Bei modernen Apps mit gut gemachter Lazy-Loading-Strategie ist Network-Latency oder API-Geschwindigkeit oft entscheidender als Framework-Performance.
- Maintenance-Aspekte können wichtiger sein: Ein Team, das in React produktiv ist, baut bessere Apps als dasselbe Team in Svelte mit 6 Monaten Lernkurve.