Zruck zum Blog, du Zniachtl
Sep. 2026·3 Min. zum LesnVo da KI gmocht

Wia da Virtual DOM wirklich funktioniert

#javascript#react#frontend

"Da Virtual DOM mocht React schnö" is a von de Sätz, de jeder nachplappert, ohne ihn wirklich erklärn zum kinna. Des is ka Zauberei, und es is nicht amoi imma schneller, ois direkt s'echte DOM anzugreifn - es is a bestimmter Kompromiss, der a bestimmtes Problem löst: rauszufinden, wos de minimale Menge an echten DOM-Änderungen is, de ma brauchn, um von oam UI-Zustand zum nächsten zu kemman, ohne dass du des händisch ausrechnen muasst.

Des Problem, des er löst

Direkte DOM-Manipulation is teuer, weil's DOM bei jeder Änderung vül orbeitet - Styles neu berechnen, Layout, und möglicherweise neu zeichnen. Wenn si dein UI-Zustand ändert und du ned genau woaßt, wos anders is, is da naive Ansatz, ois obzureißn und neu aufzubaun:

function render(state) {
  container.innerHTML = ''; // wipes everything, loses input focus/scroll position too
  container.innerHTML = renderHtml(state);
}

Des funktioniert, is aber verschwenderisch und zerstörerisch - Formularfelder valiern den Fokus, de Scroll-Position setzt si zruck, CSS-Transitions starten neu. Wos ma eigentlich will: nur de Teile vom DOM ändern, de si wirklich gändert hom, und olles andere in Ruh lossn.

Wos a Virtual-DOM-Knotn wirklich is

A Virtual-DOM-Knotn is einfach a ganz normales JavaScript-Objekt, des beschreibt, wia a Element aussehn soi - da sand no koane echten DOM-API-Aufrufe im Spiel.

// Roughly what React.createElement('button', { className: 'btn' }, 'Save') produces
const vnode = {
  type: 'button',
  props: { className: 'btn' },
  children: ['Save'],
};

A kompletter Baum von dene Objekte is billig zum erstöin - es is nur Objekt-Allokation, ka Rendering-Engine vom Browser beteiligt. Genau de Billigkeit is der ganze Witz: Du kannst bei jedem Render an komplett neichn Baum bauen, und es kost fost nix, im Gegensatz zum Neuaufbau vom echten DOM.

Diffing: Oidn Baum mit neichm Baum vergleichn

Wenn si da State ändert, baut des Framework an neichn Virtual-Tree und vergleicht ihn Knotn für Knotn mit dem vorherigen. Dieser Vergleich heißt Reconciliation, und a vereinfachte Version vom Kernalgorithmus schaut so aus:

function diff(oldVNode, newVNode) {
  if (oldVNode.type !== newVNode.type) {
    return { type: 'REPLACE', newVNode };
  }

  const propPatches = diffProps(oldVNode.props, newVNode.props);
  const childPatches = diffChildren(oldVNode.children, newVNode.children);

  return { type: 'UPDATE', propPatches, childPatches };
}

function diffProps(oldProps, newProps) {
  const patches = [];
  for (const key in newProps) {
    if (oldProps[key] !== newProps[key]) {
      patches.push({ key, value: newProps[key] });
    }
  }
  for (const key in oldProps) {
    if (!(key in newProps)) {
      patches.push({ key, value: undefined }); // removed
    }
  }
  return patches;
}

Des Ergebnis is ned a neichs DOM - es is a kleine Liste von Patches: "des Attribut hot si gändert", "der Textknotn hot si gändert", "des Element wurde hinzugfügt/entfernt". Nur de Patches wern aufs echte DOM ongwendet, über echte, gezielte element.setAttribute()- / textContent =- / appendChild()-Aufrufe.

Warum Keys bei Listn wichtig sand

Kinder-Listn per Array-Index zu vergleichn bricht zusamm, sobois Elemente umsortiert, eingfügt oda aus da Mitte entfernt wern. Ohne stabile Identität pro Element nimmt da Algorithmus an, dass Position 0 im oidn Array zu Position 0 im neichn gehört - a wenn da tatsächliche Eintrag do komplett ondas is.

<!-- Without keys: reordering "B, A, C" makes the diff think every item's
     text content changed, when really only the order changed -->
<li>A</li>
<li>B</li>
<li>C</li>
// With a stable key, the algorithm can tell "this specific item moved"
// instead of "everything here is now different"
items.map((item) => ({ type: 'li', key: item.id, children: [item.name] }));

Drum verlangt jede Listen-Rendering-API in jedem Virtual-DOM-Framework an key - des is ka Formalität, des is genau de Information, de da Diffing-Algorithmus buchstäblich ned söba herleitn kann. Merk da des, du Zniachtl.

Wos es kost

A kompletten Virtual-Tree aufzubaun und zum diffn is ned gratis - für sehr einfache, kleine UIs, oda für Updates, bei denen du die genaue Form eh scho kennst, kann direkte DOM-Manipulation tatsächlich schneller sei, weil du dir den Baumaufbau und den Vergleich komplett sparst. Da echte Gewinn vom Virtual DOM is ned reine Geschwindigkeit bei jedem einzelnen Update - es is, dass er dir a deklaratives Programmiermodell gibt ("rendere diesen State ois diesen Baum"), und trotzdem nur dort s'echte DOM berührt, wo's nötig is - ohne dass du händisch tracken muasst, wos si gändert hot.

Des is a der Grund, warum Frameworks über "Virtual-DOM-Diffing" ois einzige Strategie hinausgwachsen sand. Compiler, de die Struktur von deim Template vorher kennen (Svelte, Angulars neuere Template-Kompilierung), kinnan s'Diffing zur Laufzeit komplett überspringa und direkte Update-Anweisungen beim Build generiern, weil's ned herausfinden miassn, wos si gändert hot - sie wissn's scho vom Template.

Fazit

A Virtual DOM is a Klartext-Objekt-Beschreibung vom UI-Zustand, billig zum Bauen und Vergleichn. Das Diffing von zwoa solchen Bäum erzeugt a minimale Patch-Liste, und de is es, de tatsächlich s'echte DOM anfasst. Er is ned von Haus aus "schneller ois s'DOM" - er is a Weg, a deklaratives Rendering-Modell zum kriagn, ohne bei jeder Änderung an kompletten Neuaufbau zum zoin.

NeicherCSS Container Queries: A praktischer LeitfodnElterWeb Workers für rechenintensive Aufgaben vastehn