Vue 3 Performance 2026: Vapor Mode, Alien Signals und das Ende des Virtual DOM
Tiefer Einblick in die Performance von Vue 3.6 Vapor Mode: wie es das Virtual DOM eliminiert, das Reaktivitätssystem Alien Signals, Benchmarks gegen Solid.js und praktische Optimierungstechniken für Produktions-Apps.

Vue 3.6 Vapor Mode ist die bedeutendste Änderung der Rendering-Architektur, seit Vue in Version 2 das Virtual DOM übernommen hat. Indem Single File Components direkt in imperative DOM-Operationen kompiliert werden, eliminiert Vapor Mode den Diffing-Overhead, der die Rendering-Pipeline von Vue über Jahre geprägt hat. Zusammen mit der Neufassung der Reaktivität durch Alien Signals erreicht Vue 3.6 in Benchmarks Gleichstand mit Solid.js und Svelte 5, ohne dass Entwickler eine neue API lernen müssen.
Vapor Mode ist eine optionale Kompilierungsstrategie in Vue 3.6, die das Virtual DOM vollständig umgeht. In Vapor Mode kompilierte Komponenten verdrahten jede reaktive Abhängigkeit direkt mit dem exakten DOM-Knoten, den sie betrifft, und erzeugen so chirurgisch präzise Updates ohne jede Baumdurchquerung. Aktiviert wird das Ganze mit einem einzigen Attribut: <script setup vapor>.
So funktioniert das Virtual DOM von Vue, und warum es zum Engpass wurde
Das Virtual-DOM-Muster (VDOM), von React populär gemacht und von Vue 2 übernommen, erstellt eine leichtgewichtige JavaScript-Repräsentation des tatsächlichen DOM-Baums. Bei jeder Zustandsänderung erzeugt Vue einen neuen VDOM-Baum, vergleicht ihn mit dem vorherigen und patcht nur die geänderten Knoten in das reale DOM.
Dieser Ansatz funktioniert für die meisten Anwendungen gut. Der Diffing-Algorithmus läuft in O(n)-Zeit, und der Compiler von Vue optimiert statische Teilbäume bereits aus dem Diff-Pfad heraus. Doch der Overhead summiert sich in bestimmten Szenarien:
- Große Listen mit Hunderten von Zeilen lösen bei jedem Update vollständige Teilbaum-Vergleiche aus
- Häufige Zustandsänderungen (Animationen, Echtzeitdaten) erzeugen VDOM-Churn, den der Garbage Collector aufräumen muss
- Tiefe Komponentenbäume vervielfachen die Kosten für Baumdurchquerung und Patch-Erzeugung
Der Template-Compiler von Vue 3 führte mehrere VDOM-Optimierungen ein: statisches Hoisting, Patch-Flags und Block-Trees. Diese reduzierten unnötige Arbeit, doch die grundlegende Architektur erforderte weiterhin das Erzeugen, Vergleichen und Verwerfen von JavaScript-Objekten bei jedem Render-Zyklus.
Vue 3.6 Vapor Mode: Das Virtual DOM wegkompilieren
Vapor Mode verfolgt einen völlig anderen Ansatz. Statt Templates in Render-Funktionen zu kompilieren, die VDOM-Knoten zurückgeben, erzeugt der Vapor-Compiler Code, der DOM-Elemente direkt erstellt und aktualisiert. Jede reaktive Bindung bildet eine konkrete DOM-Mutation ab, ohne dass eine Zwischenrepräsentation nötig wäre.
So kompiliert eine Standard-Vue-Komponente unter den beiden Modi unterschiedlich:
<!-- Counter.vue -->
<script setup vapor>
import { ref } from 'vue'
const count = ref(0)
const increment = () => count.value++
</script>
<template>
<button @click="increment">
Count: {{ count }}
</button>
</template>Im klassischen VDOM-Modus kompiliert dieses Template zu einer Render-Funktion, die einen virtuellen Knotenbaum zurückgibt. Bei jedem Klick erzeugt Vue einen neuen VDOM-Baum, vergleicht ihn mit dem vorherigen, erkennt die geänderte Textmenge und patcht das reale DOM.
Im Vapor Mode erzeugt der Compiler etwas, das eher so aussieht:
// Simplified Vapor compilation output
const button = document.createElement('button')
const text = document.createTextNode('Count: 0')
button.appendChild(text)
// Direct binding: reactive source -> DOM mutation
effect(() => {
text.nodeValue = `Count: ${count.value}`
})
button.addEventListener('click', increment)Der reaktive Effekt verdrahtet count direkt mit text.nodeValue. Keine VDOM-Erzeugung, kein Diffing, kein Patching. Die Zustandsänderung löst genau eine DOM-Mutation aus.
Vapor Mode in einem Projekt aktivieren
Vapor Mode arbeitet auf Komponentenebene. Es existieren zwei Integrationsstrategien:
import { createVaporApp } from 'vue'
import App from './App.vue'
createVaporApp(App).mount('#app')import { createApp, vaporInteropPlugin } from 'vue'
import App from './App.vue'
createApp(App)
.use(vaporInteropPlugin)
.mount('#app')Der hybride Ansatz ermöglicht eine schrittweise Migration. Performancekritische Komponenten, darunter Datentabellen, Echtzeit-Dashboards und animationslastige Ansichten, können auf Vapor umgestellt werden, während der Rest der Anwendung weiterhin die Standard-VDOM-Laufzeit nutzt. Beide Komponententypen koexistieren im selben Komponentenbaum.
Vapor Mode setzt die Composition API mit <script setup> voraus. Die Options API, app.config.globalProperties, getCurrentInstance(), v-memo und elementbezogene Lifecycle-Events (@vue:mounted usw.) werden nicht unterstützt. Custom Directives nutzen eine andere Schnittstelle, die reaktive Getter statt Binding-Objekte erwartet. Reine Vapor-Anwendungen unterstützen <Suspense> nicht, allerdings funktioniert Suspense, wenn Vapor-Komponenten in einem VDOM-Elternelement eingebettet sind.
Änderungen bei der Event-Delegation in Vue 3.6 RC
Zwischen der Beta- und der RC-Version hat das Vue-Team die Event-Behandlung in Vapor Mode geändert. In der Beta delegierte Vapor Events automatisch auf Dokumentebene. Ab RC.2 werden Listener standardmäßig direkt an Elemente gebunden. Um für große Listen die Dokumentebenen-Delegation zu nutzen, kann der explizite .delegate-Modifier verwendet werden:
<template>
<ul>
<li v-for="item in items" :key="item.id">
<button @click.delegate="selectItem(item)">
{{ item.name }}
</button>
</li>
</ul>
</template>Diese Änderung gleicht Vapor an die Standard-Vue-Semantik bezüglich stopPropagation() an und entspricht den Entwicklererwartungen an die Event-Behandlung.
Alien Signals: Die neue Reaktivitäts-Engine von Vue
Vue 3.6 bringt neben Vapor Mode eine zweite große Änderung: eine vollständige Neufassung von @vue/reactivity auf Basis der Bibliothek Alien Signals. Alien Signals, entwickelt von Johnson Chu, implementiert einen Push-Pull-Reaktivitätsalgorithmus, der sowohl die Speicherzuweisung als auch den Rechenaufwand reduziert.
Das Push-Pull-Modell arbeitet in zwei Phasen:
- Push-Phase: Wenn sich ein Signal (eine reaktive Quelle) ändert, propagiert es ein Dirty-Flag an alle abhängigen Computed Properties. Diese Durchquerung ist günstig, da sie lediglich boolesche Flags umsetzt, ohne Berechnungen auszuführen.
- Pull-Phase: Wenn eine Computed Property gelesen wird, prüft sie ihr Dirty-Flag. Ist sie dirty, berechnet sie neu. Ist sie clean, gibt sie sofort den zwischengespeicherten Wert zurück.
Dieses Design eliminiert unnötige Neuberechnungen. Im Reaktivitätssystem von Vue 3.5 hätte eine von drei Signalen abhängige Computed Property bei jeder Signaländerung neu gerechnet, selbst wenn das Ergebnis gleich blieb. Alien Signals rechnet nur dann neu, wenn der Wert tatsächlich gelesen wird und sich mindestens eine Abhängigkeit geändert hat.
import { ref, computed, watch } from 'vue'
const firstName = ref('Jane')
const lastName = ref('Doe')
const isActive = ref(true)
// This computed only recalculates when read AND dirty
const displayName = computed(() => {
return isActive.value
? `${firstName.value} ${lastName.value}`
: 'Inactive User'
})
// Changing isActive marks displayName as dirty
// But no computation runs until something reads displayName.value
isActive.value = false
// NOW the recalculation happens
console.log(displayName.value) // 'Inactive User'Auch die interne Datenstruktur hat sich geändert. Alien Signals ersetzt die Set-basierte Abhängigkeitsverfolgung durch doppelt verkettete Listen, was den Speicherbedarf pro reaktiver Abhängigkeit senkt und die Durchquerungsgeschwindigkeit beim Aufräumen verbessert.
Benchmark-Ergebnisse: Alien Signals in der Praxis
Die Zahlen aus den Vue-3.6-RC-Benchmarks zeigen durchgängige Verbesserungen gegenüber Vue 3.5:
| Metrik | Vue 3.5 | Vue 3.6 (Alien Signals) | Verbesserung |
|---|---|---|---|
| Speicher pro reaktivem Ref | Basiswert | -14% | Geringere Allokation |
| Computed-Neuberechnung | Basiswert | -20% Ø | Weniger unnötige Durchläufe |
| Komponenten-Mount (100k) | ~300ms | ~100ms | 3x schneller |
| First Contentful Paint | Basiswert | typ. 0,7s | Geringerer Framework-Overhead |
| Basis-Bundle-Größe | ~16KB | <10KB | -37% |
Diese Verbesserungen gelten automatisch für alle Vue-3.6-Anwendungen. Anders als Vapor Mode, das pro Komponente aktiviert werden muss, ist das Alien-Signals-Reaktivitätssystem in Vue 3.6 der Standard.
Bereit für deine Vue.js / Nuxt.js-Interviews?
Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.
Praktische Techniken zur Performance-Optimierung in Vue 3
Vapor Mode und Alien Signals adressieren den Overhead auf Framework-Ebene, doch die Performance auf Anwendungsebene hängt weiterhin davon ab, wie Komponenten strukturiert sind. Diese Techniken gelten sowohl für VDOM- als auch für Vapor-Komponenten. Weitere Informationen zum Erstellen wiederverwendbarer, performance-optimierter Logik finden sich im Leitfaden zu erweiterten Vue-3-Composables.
Flache Reaktivität für große Datenstrukturen
Tiefe Reaktivität umhüllt jede verschachtelte Eigenschaft mit einem Proxy. Bei großen Datensätzen (API-Antworten, Konfigurationsobjekten, zwischengespeichertem State) erzeugt das Tausende unnötiger Proxy-Wrapper. shallowRef und shallowReactive beschränken die Reaktivität auf die oberste Referenzebene.
import { shallowRef, triggerRef } from 'vue'
interface Product {
id: number
name: string
variants: { sku: string; price: number }[]
}
// Only the ref itself is reactive, not the nested properties
const products = shallowRef<Product[]>([])
// Fetching data — assign the new array to trigger reactivity
async function fetchProducts() {
const response = await fetch('/api/products')
products.value = await response.json() // triggers update
}
// Mutating nested data — must manually trigger
function updatePrice(productId: number, sku: string, newPrice: number) {
const product = products.value.find(p => p.id === productId)
const variant = product?.variants.find(v => v.sku === sku)
if (variant) {
variant.price = newPrice
triggerRef(products) // explicit trigger required
}
}Die v-memo-Direktive für aufwändiges Listen-Rendering
Bei VDOM-Komponenten, die lange Listen rendern, speichert v-memo die Render-Ergebnisse von Teilbäumen anhand von Abhängigkeitswerten zwischen. Das VDOM überspringt das Diffing vollständig für memoisierte Teilbäume, deren Abhängigkeiten sich nicht geändert haben. Hinweis: v-memo ist in Vapor Mode nicht verfügbar.
<!-- ProductGrid.vue -->
<script setup>
import { ref } from 'vue'
const products = ref([])
const selectedId = ref(null)
</script>
<template>
<div class="grid">
<div
v-for="product in products"
:key="product.id"
v-memo="[product.id === selectedId, product.price]"
:class="{ selected: product.id === selectedId }"
>
<h3>{{ product.name }}</h3>
<span>{{ product.price }}</span>
</div>
</div>
</template>Das v-memo-Array [product.id === selectedId, product.price] weist Vue an: dieses Element nicht neu rendern, solange sich Auswahlstatus oder Preis nicht ändern. Bei einer Liste von 500 Produkten, von denen nur eines ausgewählt wird, reduziert das die VDOM-Arbeit von 500 Teilbaum-Diffs auf 2 (das zuvor und das neu ausgewählte Element).
Asynchrone Komponenten mit Suspense für Code-Splitting
Das Lazy-Loading schwergewichtiger Komponenten hält das initiale Bundle schlank. Vues defineAsyncComponent in Kombination mit Suspense behandelt den Ladezustand deklarativ. Einen tieferen Einblick in Suspense-Patterns und Randfälle bietet der Leitfaden zu Teleport und Suspense.
<!-- Dashboard.vue -->
<script setup>
import { defineAsyncComponent } from 'vue'
// Heavy charting library loaded only when needed
const AnalyticsChart = defineAsyncComponent(() =>
import('./components/AnalyticsChart.vue')
)
const DataExport = defineAsyncComponent({
loader: () => import('./components/DataExport.vue'),
delay: 200, // show loading after 200ms
timeout: 10000, // fail after 10s
})
</script>
<template>
<Suspense>
<template #default>
<AnalyticsChart />
<DataExport />
</template>
<template #fallback>
<div class="skeleton-loader" />
</template>
</Suspense>
</template>Vapor Mode vs. VDOM: Wann welcher Ansatz passt
Vapor Mode ist kein universeller Ersatz für das Virtual DOM. Jeder Kompilierungsmodus hat Stärken, die zu unterschiedlichen Komponentenprofilen passen.
| Szenario | Empfohlener Modus | Grund |
|---|---|---|
| Datentabellen (1000+ Zeilen) | Vapor | Eliminiert VDOM-Overhead pro Zeile |
| Echtzeit-Dashboards | Vapor | Häufige Updates profitieren von direkter DOM-Bindung |
| Animationslastige Komponenten | Vapor | Kein GC-Druck durch VDOM-Churn |
| Drittanbieter-VDOM-Komponentenbibliotheken | VDOM | Interop-Schicht erhöht die Komplexität |
| Komponenten mit Options API | VDOM | Vapor erfordert die Composition API |
| Formulare mit komplexer Validierung | Beliebig | In beiden Modi minimaler Render-Overhead |
| Statische Inhaltsseiten | Beliebig | SSG/SSR übernimmt die Hauptarbeit |
Der empfohlene Migrationspfad: zuerst die Anwendung mit dem Performance-Tab der Vue DevTools profilieren. Die Komponenten mit der höchsten Render-Zeit und Re-Render-Häufigkeit identifizieren. Diese auf Vapor Mode umstellen, die Wirkung messen und von dort ausweiten.
Interview-Fragen: Vue 3 Performance und Vapor Mode
Diese Fragen spiegeln wider, was Engineering-Teams 2026 bei der Bewertung von Vue-Expertise stellen. Jede Antwort fasst die technische Argumentation zusammen, die ein Interviewer erwartet.
F: Welches Problem löst Vapor Mode, und wie unterscheidet es sich von den VDOM-Optimierungen, die Vue bereits hatte?
Der VDOM-Compiler von Vue 3 optimierte bereits statische Teilbäume, fügte Patch-Flags hinzu und implementierte Block-Trees, um unnötige Diffs zu überspringen. Das reduzierte den VDOM-Overhead, eliminierte ihn aber nicht: jede Zustandsänderung erforderte weiterhin das Erzeugen von VDOM-Knoten, das Durchqueren des Baums und das Generieren von Patches. Vapor Mode entfernt diese gesamte Pipeline. Der Compiler bildet reaktiven State direkt auf DOM-Mutationen ab, sodass eine Zustandsänderung exakt die benötigten DOM-Operationen auslöst. Keine Zwischendatenstrukturen, kein Diffing-Algorithmus, keine Garbage Collection verworfener VDOM-Knoten.
F: Können Vapor- und VDOM-Komponenten in derselben Anwendung koexistieren?
Ja. Das vaporInteropPlugin erlaubt beide Komponententypen in einem einzigen Komponentenbaum. Ein VDOM-Eltern kann Vapor-Kinder rendern und umgekehrt, mit einigen Einschränkungen. Vapor-Slots können slots.default() nicht innerhalb einer VDOM-Komponente verwenden (stattdessen renderSlot nutzen). Suspense wird für Vapor-Komponenten unterstützt, wenn sie in einem VDOM-Elternelement eingebettet sind, nach Korrekturen in RC.3. Die Interoperabilität mit VDOM-basierten Komponentenbibliotheken (Vuetify, PrimeVue) sollte vor dem Produktiveinsatz gründlich getestet werden.
F: Erläutern Sie das Push-Pull-Reaktivitätsmodell der Alien Signals in Vue 3.6.
Das Push-Pull-Modell teilt reaktive Updates in zwei Phasen. In der Push-Phase propagiert das System bei einer Wertänderung eines Signals ein Dirty-Flag abwärts durch alle abhängigen Computed Properties. Das ist günstig, da nur boolesche Flags umgesetzt werden. In der Pull-Phase prüft eine Computed Property beim tatsächlichen Lesen, ob sie dirty ist. Ist sie dirty, rechnet sie aus ihren Abhängigkeiten neu. Ist sie clean, gibt sie den zwischengespeicherten Wert zurück. Das vermeidet das eifrige Neuberechnen von Computed Properties, die in einem bestimmten Update-Zyklus womöglich nie gelesen werden.
F: Wann sollte shallowRef statt ref in einer Vue-3-Anwendung verwendet werden?
shallowRef ist angebracht, wenn die Datenstruktur groß ist und nur eine Neuzuweisung auf oberster Ebene Reaktivität auslösen soll. Anwendungsfälle sind API-Antwort-Caches, Konfigurationsobjekte und große Arrays, bei denen einzelne Element-Mutationen manuell mit triggerRef() gesteuert werden. Tiefe Reaktivität umhüllt jede verschachtelte Eigenschaft mit einem Proxy, was unnötiger Overhead für Daten ist, die als Ganzes ersetzt statt an Ort und Stelle mutiert werden.
Weitere Vue.js-Interviewfragen zu Composables und Reaktivitätsmustern auf SharpSkill üben.
Der offizielle Performance-Leitfaden von Vue.js behandelt weitere Optimierungstechniken, darunter Prop-Stabilität, virtuelles Scrolling und SSR-Streaming. Die Release-Notes zu Vue 3.6 RC dokumentieren die neuesten Vapor-Mode-APIs und bekannte Einschränkungen.
Sources
- Vue 3.6 RC Release Notes: Offizielles Changelog mit Dokumentation der RC.7-Änderungen und des Vapor-Mode-Status
- TODOvue: Vue 3.6 RC Status und Einschränkungen: Detaillierte Analyse der Breaking Changes in RC.2/RC.3 einschließlich Event-Delegation
- Vue 3.6 RC Upgrade-Leitfaden: Migrationspfad von Vue 3.5 zu 3.6 RC
- Alien Signals GitHub: Quellcode und Dokumentation der neuen Reaktivitäts-Engine
Fang an zu üben!
Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.
Bedeutung von Vue 3.6 Vapor Mode für Produktionsanwendungen
Vapor Mode kompiliert Vue-SFCs in direkte DOM-Operationen und eliminiert Erzeugung, Diffing und Patching des Virtual DOM vollständig. Die Aktivierung erfolgt pro Komponente mit <script setup vapor>, ohne dass eine anwendungsweite Migration erforderlich wäre.
Alien Signals, die neue Standard-Reaktivitäts-Engine, senkt den Speicherverbrauch um 14% und verbessert die Performance von Computed Properties durch faule Push-Pull-Auswertung.
shallowRef für große Datenstrukturen, v-memo für aufwändiges Listen-Rendering (nur VDOM) und defineAsyncComponent für Code-Splitting nutzen. Diese Muster gelten sowohl im VDOM- als auch im Vapor-Modus.
Vapor Mode erfordert die Composition API mit <script setup>. Options API, getCurrentInstance(), v-memo und globalProperties werden nicht unterstützt.
Zuerst mit den Vue DevTools profilieren, wirkungsstarke Komponenten auf Vapor umstellen, messen und iterieren.
Vue 3.6 befindet sich seit September 2026 in der Release-Candidate-Phase. RC.7 adressiert Hydration, KeepAlive, Teleport und Suspense-Interop mit VDOM. Vor dem Produktiveinsatz gründlich testen, aber die API-Oberfläche ist stabil genug für eine ernsthafte Evaluierung.
Findest du den Bug in Vue.js / Nuxt.js?
Ein echter Codeausschnitt, ein versteckter Bug, ein Versuch pro Tag. Zum Ausprobieren ohne Konto.

Geschrieben von
Anthony Fillion-MailletGründer von SharpSkill
Seit über 10 Jahren Fullstack-Entwickler. Er leitet SharpSkill und verantwortet alles, was hier erscheint.
Aktualisiert am 7. September 2026
Tags
Teilen
Verwandte Artikel

Vue 3 Reactivity Transform 2026: $ref, $computed und Interview-Fragen
Umfassende Analyse des Vue 3 Reactivity Transform mit $ref, $computed und $$ Makros. Praktische Codebeispiele, Migration von ref() zu $ref, und häufige Vue-Interview-Fragen für Senior-Entwickler.

Fortgeschrittene Vue 3 Composables: Wiederverwendbare Muster und Interviewfragen 2026
Umfassender Leitfaden zu fortgeschrittenen Vue 3 Composables mit wiederverwendbaren Mustern, asynchroner Fehlerbehandlung, Dependency Injection, Formularvalidierung und aktuellen Interviewfragen fuer 2026.

Vue-3-Testing 2026: Vitest, Vue Test Utils und Interviewfragen
Ein praxisnaher Leitfaden zum Vue-Testing 2026: Vitest konfigurieren, Komponenten mit Vue Test Utils mounten, Composables und Pinia-Stores testen, APIs mocken, Coverage messen und die Interviewfragen, die Recruiting-Teams stellen.