Zurück zur Startseite

Web Components: Mythen und Wahrheit über Custom Elements

Der Artikel entlarvt Mythen über web components: property passing, Shadow DOM, hooks. Bietet Code-Lösungen und hebt Stärken für komplexe Dashboards und Widgets hervor.

Entlarvung von Mythen über web components für Entwickler
Advertisement 728x90

Web Components: Mythen entkräften und echte Möglichkeiten erkunden

Web Components werden oft dafür kritisiert, dass sie angeblich nur die Übergabe von String-Eigenschaften über Attribute erlauben. Dieses Missverständnis rührt von einer Fehlinterpretation des attributeChangedCallback-Mechanismus her. HTML-Attribute sind ein statischer Teil des Markups und nicht direkt mit der JS-Laufzeitumgebung verbunden. Um Objekte, Arrays oder Primitiva zu übergeben, verwenden Sie Getter/Setter in der Komponentenklasse. Browser ermöglichen das Setzen von Eigenschaften jeglichen Typs direkt über die DOM-API oder Proxies.

class MyElement extends HTMLElement {
  set data(value) {
    this._data = value;
    this.render();
  }
}

Shadow DOM bietet Stil- und DOM-Isolation und schützt vor externen Konflikten. Die Kritik an der Isolation als Fehler ignoriert die Wahlmöglichkeit: Custom Elements funktionieren auch ohne Shadow DOM. Für die Anpassung verwenden Sie CSS-Variablen und ::part():

my-component::part(button) {
  background: var(--accent-color);
}

Der Mythos der Stilduplizierung: Adopted Style Sheets ermöglichen die Anwendung gemeinsamer Stile auf alle Shadow-DOM-Instanzen.

Google AdInline article slot

Der Lebenszyklus beginnt im Konstruktor, nicht bei der Verbindung mit dem DOM. Komponenten werden im Speicher erstellt und über DocumentFragment zur Virtualisierung ohne Rendering manipuliert.

Halbwahrheiten: Registry und Lifecycle-Hooks

Das globale Custom-Elements-Registry erfordert eindeutige Namen. Die Lösung sind Präfixe (z.B. app-button) und try/catch während der Registrierung:

try {
  customElements.define('app-button', ButtonElement);
} catch (e) {
  console.warn('Name conflict:', e);
}

Kollisionen werden durch Tests erkannt. Flache Namensräume sind ein Standardmuster in JS, DNS und HTML.

Google AdInline article slot

Die connectedCallback/disconnectedCallback-Hooks werden ausgelöst, wenn sich das Element im DOM bewegt. Die Lösung ist ein Initialisierungs-Flag:

connectedCallback() {
  if (this._initialized) return;
  this._initialized = true;
  this.init();
}

Eine Deregistrierung ist unmöglich, aber das ist ein Vorteil: Browser cachen den Konstruktor ohne Overhead.

Echte Nuancen und Lösungen

HTML-Parsing löst connectedCallback beim öffnenden Tag aus, bevor der Inhalt verarbeitet wird. DOM-APIs sind nicht verfügbar. Verwenden Sie defer oder type="module" für verzögerte Initialisierung. Eine Alternative ist customElements.whenDefined():

Google AdInline article slot
const button = document.querySelector('app-button');
await customElements.whenDefined('app-button');
button.method();

Um den Zugriff auf Kindelemente zu garantieren, verwenden Sie renderCallback oder ähnliche Hooks.

Stärken von Web Components

Web Components verknüpfen HTML-Markup nativ mit JS. Benutzerdefinierte Tags dienen als Marker für die Integration auf dem Server oder Client ohne Vendor-Lock-in.

Atomare Lebenszyklusverwaltung: Browser informieren unabhängig von Frameworks über Verbindung/Trennung.

Ein grundlegendes Modell für Lit, Symbiote.js und Micro-Frontends. Funktioniert mit React, Vue, Angular, SPAs und SSR.

  • Isolation ohne Overhead: Shadow DOM ist optional.
  • Native Reaktivität: Eigenschaften + Proxies.
  • Vielseitigkeit: von Widgets bis zu Dashboards mit WebSocket und Grafik.
  • Virtualisierung: DocumentFragment für Listen mit 100k+ Elementen.
  • Styling: CSS-Vars, ::part(), Adopted Style Sheets.

Wichtige Erkenntnisse

  • Eigenschaften jeglichen Typs werden über Getter/Setter übergeben; Attribute sind nur für Strings.
  • Shadow DOM isoliert, kann aber bei Bedarf deaktiviert werden; Stil über Vars und ::part.
  • Das globale Registry wird mit Präfixen und Tests gelöst; Kollisionen sind selten.
  • Die connected/disconnected-Hooks mit einem Flag verhindern doppelte Initialisierung.
  • Parsing-Asynchronität wird mit defer/module oder whenDefined behoben.

— Editorial Team

Advertisement 728x90

Weiterlesen