Reaktivität ohne Framework: Was natives JavaScript heute leisten kann
Sie möchten reaktives UI-Verhalten – Zustandsänderungen, die automatisch das DOM aktualisieren – aber Sie wollen nicht 40 KB Framework-Code für ein einfaches Widget ausliefern. Gute Nachrichten: Reaktivität mit Vanilla JavaScript ist vollständig umsetzbar mit APIs, die seit Jahren in Browsern stabil sind.
Dieser Artikel behandelt die nativen Werkzeuge, die Ende 2025 für den Aufbau reaktiver UIs verfügbar sind: Proxy-basierter reaktiver State, EventTarget und CustomEvent für Pub/Sub sowie Browser-Observer für DOM-bewusste Reaktionen. Sie erfahren, was heute funktioniert, was kommt und wo diese Muster auf Framework-Interna abbilden.
Wichtigste Erkenntnisse
- Proxy-Objekte fangen Eigenschaftsänderungen ab und ermöglichen automatische DOM-Updates ohne Framework-Abhängigkeiten
- EventTarget und CustomEvent bieten eine native Pub/Sub-Schicht für entkoppelte Komponentenkommunikation
- Browser-Observer (MutationObserver, IntersectionObserver, ResizeObserver) behandeln DOM- und Layout-Reaktivität
- Der TC39-Signals-Vorschlag könnte Reaktivitätsprimitive standardisieren, aber aktuelle Proxy + EventTarget-Muster erzielen heute bereits ähnliche Ergebnisse
Was Reaktivität tatsächlich bedeutet
Reaktivität ist eine einfache Schleife: Zustandsänderungen lösen UI-Updates aus. Frameworks automatisieren dies mit virtuellen DOMs, Compilern oder feinkörnigem Dependency-Tracking. Aber die zugrundeliegende Mechanik basiert auf JavaScript-Features, die Sie direkt nutzen können.
Das Kernmuster:
- Speichern Sie den State in einer nachverfolgbaren Struktur
- Benachrichtigen Sie Subscriber bei Zustandsänderungen
- Aktualisieren Sie nur das relevante DOM
Native Browser-APIs bewältigen jeden Schritt ohne externe Abhängigkeiten.
Proxy-basierter reaktiver State
Das Proxy-Objekt fängt Eigenschaftszugriffe und -zuweisungen ab. In Kombination mit Reflect bildet es die Grundlage für Proxy-basierten reaktiven State.
function createReactiveStore(initial, onChange) {
return new Proxy(initial, {
set(target, prop, value) {
const result = Reflect.set(target, prop, value)
onChange(prop, value)
return result
}
})
}
const state = createReactiveStore({ count: 0 }, (prop, value) => {
document.getElementById('count').textContent = value
})
state.count = 5 // DOM wird automatisch aktualisiert
Dieses Muster fühlt sich „signal-artig” an – Sie schreiben in den State, und Effekte werden ausgeführt. Das Reaktivitätssystem von Vue 3 verwendet intern Proxy genau aus diesem Grund.
Einschränkung: Proxy-Traps werden nur bei Mutationen ausgelöst, die auf das proxierte Objekt selbst angewendet werden. Wenn verschachtelte Objekte oder Arrays nicht ebenfalls in eigene Proxies eingewickelt sind, werden Änderungen darin (wie array.push()) nicht nachverfolgt. Viele Entwickler verwenden immutable Updates (z.B. state.items = [...state.items, newItem]), um zu garantieren, dass Updates ausgelöst werden.
EventTarget und CustomEvent als Pub/Sub-Schicht
Für entkoppelte Komponentenkommunikation bietet EventTarget einen nativen Pub/Sub-Mechanismus. Jedes Objekt kann zu einem Event-Emitter werden.
const bus = new EventTarget()
// Abonnieren
bus.addEventListener('state-change', (e) => {
console.log('Neuer Wert:', e.detail)
})
// Veröffentlichen
bus.dispatchEvent(new CustomEvent('state-change', {
detail: { count: 10 }
}))
Dieses Muster ermöglicht reaktive UI mit nativen Browser-APIs. Komponenten abonnieren Events, reagieren auf Änderungen und bleiben entkoppelt. Anders als benutzerdefinierte Pub/Sub-Implementierungen integriert sich EventTarget mit Browser-DevTools und folgt Standard-Event-Semantik.
Discover how at OpenReplay.com.
Browser-Observer für DOM-Reaktivität
Wenn Sie auf DOM- oder Layout-Änderungen reagieren müssen – nicht nur auf State – schließen Browser-Observer die Lücke.
MutationObserver überwacht DOM-Modifikationen:
const observer = new MutationObserver((mutations) => {
mutations.forEach(m => console.log('DOM geändert:', m))
})
observer.observe(document.body, { childList: true, subtree: true })
IntersectionObserver verfolgt die Sichtbarkeit von Elementen – nützlich für Lazy Loading oder Analytics.
ResizeObserver reagiert auf Größenänderungen von Elementen ohne Polling.
Diese APIs sind seit langem stabil und produktionsreif. Sie ergänzen zustandsgesteuerte Reaktivität, indem sie Fälle behandeln, in denen externe Faktoren das DOM modifizieren.
Der TC39-Signals-Vorschlag: Was kommt
Es gibt zunehmendes Interesse an der Standardisierung von Reaktivitätsprimitiven. Der TC39-Signals-Vorschlag zielt darauf ab, ein gemeinsames Modell zu definieren, das Frameworks teilen könnten.
Wichtig: Stand 2025 ist dies noch ein Vorschlag – kein ausgeliefertes JavaScript-Feature. Frameworks wie Solid, Angular und Preact haben signal-artige Muster übernommen, die das Design des Vorschlags beeinflussen. Aber Sie können „native Signals” heute noch nicht in Browsern verwenden.
Die oben genannten Proxy + EventTarget-Muster erreichen ähnliche Ziele. Falls Signals standardisiert werden, sollte die Migration unkompliziert sein, da das mentale Modell übereinstimmt.
Das richtige Muster wählen
| Muster | Am besten für | Kompromiss |
|---|---|---|
| Proxy | Lokaler Komponenten-State | Verfolgt nur Änderungen am proxierten Objekt, es sei denn, verschachtelte Werte sind ebenfalls proxiert |
| EventTarget | Komponentenübergreifende Kommunikation | Manuelle Verdrahtung |
| MutationObserver | Reaktion auf externe DOM-Änderungen | Performance-Overhead |
Für kleine Apps und Widgets deckt die Kombination von Proxy-basiertem State mit EventTarget die meisten reaktiven UI-Anforderungen ohne Framework-Overhead ab.
Fazit
Reaktivität ohne Framework ist heute praktikabel. Proxy behandelt State-Tracking, EventTarget bietet Pub/Sub, und Browser-Observer reagieren auf DOM-Änderungen. Diese APIs sind stabil, gut dokumentiert und lassen sich zu einem leichtgewichtigen reaktiven Kern zusammensetzen.
Sie brauchen kein Framework, um feinkörnige Reaktivität zu erhalten. Sie müssen die Primitive verstehen, auf denen Frameworks aufgebaut sind – und das tun Sie jetzt.
FAQs
Proxy-Traps werden nur bei direkter Eigenschaftszuweisung auf das proxierte Objekt ausgelöst. Für verschachtelte Objekte müssen Sie entweder jedes verschachtelte Objekt rekursiv in einen eigenen Proxy einwickeln oder die gesamte verschachtelte Struktur bei Änderungen ersetzen. Die meisten Entwickler entscheiden sich für immutable Update-Muster wie Spreading, um neue Referenzen zu erstellen.
EventTarget ist eine native Browser-API, die sich in DevTools integriert und Standard-Dispatch-Semantik folgt. Vollständiges Bubbling und Capturing gelten nur, wenn das Event-Target Teil des DOM-Baums ist. Benutzerdefinierte Bibliotheken bieten möglicherweise zusätzliche Features wie Wildcard-Listener oder einmalige Subscriptions, aber EventTarget benötigt keine Abhängigkeiten und funktioniert konsistent in allen modernen Browsern.
Verwenden Sie MutationObserver, wenn Sie auf DOM-Änderungen reagieren müssen, die durch externen Code, Drittanbieter-Skripte oder Browser-Erweiterungen vorgenommen werden. Proxy verfolgt JavaScript-Zustandsänderungen, die Sie kontrollieren. MutationObserver überwacht den tatsächlichen DOM-Baum unabhängig davon, was die Änderung verursacht hat. Sie dienen unterschiedlichen Zwecken und arbeiten oft zusammen.
Der Signals-Vorschlag zielt darauf ab, Reaktivitätsprimitive zu standardisieren, die Frameworks teilen können, nicht bestehende APIs zu ersetzen. Proxy und EventTarget bleiben gültige Ansätze. Falls Signals ausgeliefert werden, werden sie diese Muster wahrscheinlich ergänzen, indem sie eine Standardschnittstelle für feinkörniges Dependency-Tracking über verschiedene Bibliotheken hinweg bereitstellen.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.