Zum Inhalt springen
CASOON

Svelte kompakt erklärt – Teil 3: Svelte intern – Reaktivität, Stores und Komponenten-Architektur

Wie Svelte Reaktivität, State-Management und Komponentenstruktur neu denkt.

2 Minuten
Svelte kompakt erklärt – Teil 3: Svelte intern – Reaktivität, Stores und Komponenten-Architektur
#Svelte #Reaktivität #Stores #Komponenten

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:

src/ ├── lib/ │ ├── components/ │ ├── stores/ │ ├── utils/ │ └── styles/ ├── routes/ │ ├── +page.svelte │ ├── about/ │ │ └── +page.svelte
  • 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 (mit writable und derived) 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/setContext funktionieren, 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() ersetzt let für reaktive Werte: Explizitere Markierung, bessere TypeScript-Inferenz.
  • $derived() ersetzt $:: Saubere Trennung zwischen Side-Effects ($effect) und Derived-Values.
  • $props() für Komponenten-Props: Ersetzt export 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.