Ein Blick auf Web Components

Keine Kommentare

Wenn es um moderne Web-Anwendungen geht, dann führt momentan (fast) kein Weg an Angular und React vorbei. Natürlich gibt es hier sehr interessante Alternativen wie Vue.js, Ember und Co, in größeren Projekten spielten diese aber 2017 eine wesentlich kleinere Rolle. Natürlich stellt sich die Frage, wie es in einem schnelllebigen Ökosystem rund um JavaScript & Co in den nächsten Jahren weitergeht. Sicherlich werden auch 2018 komponentenbasierte Frameworks den Markt dominieren – am Horizont zeichnet sich aber seit einer Weile eine Alternative ab: Web Components.

Bei Web Components handelt es sich um eine Reihe von Features, die momentan vom W3C den HTML- und DOM-Spezifikationen hinzugefügt werden. Web Components erlauben es, wiederverwendbare Komponenten für Web-Anwendungen zu erstellen. Ein Konzept, das wir von Angular und React schon kennen.

In diesem Beitrag werfen wir einen Blick auf diese Features und welche Möglichkeiten sie bieten.

Beispiel mit React

Nehmen wir als Beispiel eine Liste von Strings, die wir darstellen möchten. In React sieht das dann so aus:

Das fühlt sich schon sehr nach “eigenem” HTML an. Während React aber nur erlaubt, die eigenen Komponenten zu verwenden, ermöglichen es Web Components, eigene HTML-Elemente zu definieren, die dann auch wie normales HTML in eine Seite integriert werden können. Sie lassen sich also auch serverseitig einfach einsetzen. Ein weiterer Vorteil: Sie verhalten sich wie HTML und können daher auch mit jeder JavaScript-Bibliothek und jedem Framework verwendet werden, das mit HTML umgehen kann (z.B. für Events).

Außerdem basieren Web Components auf Web-Standards und haben daher eine höhere Zukunftssicherheit. Bei der Bewertung müssen wir aber auch einen Nachteil berücksichtigen, den Web Components momentan leider mitbringen: Noch sind Web Components nicht in jedem Browser ohne Weiteres verfügbar. Man kann diese Funktionalität aber über Polyfills nachrüsten.

Polyfills

Polyfills erlauben es, Funktionen, die im Browser momentan nicht unterstützt werden, nachzurüsten. Dies kann bedeuten, dass die Performance nicht der nativen Implementierung entspricht und ist zusätzlicher Ballast für den Nutzer, da das jeweilige Skript geladen und ausgeführt werden muss.

Überblick

Wenn wir von Web Components sprechen, meinen wir vier Features, die wir uns im Folgenden genauer ansehen werden:

  • HTML Templates: Eine Möglichkeit mit Hilfe des <template> Elements HTML Vorlagen im Dokument zu hinterlegen. Diese können dann mit Hilfe von JavaScript manipuliert werden
  • HTML Imports: Möglichkeit HTML in andere Dokumente zu laden
  • Shadow DOM: innerhalb von HTML-Elementen ein eigenes, unabhängiges, DOM erzeugen und innerhalb von diesem neue Komponenten hinzufügen und stylen
  • Custom Elements: API um eigene HTML Elemente zu schreiben

    In diesem Beitrag sehen wir uns diese Features an. Der zugehörige Code liegt ebenfalls auf GitHub oder kann in einer HTML-Datei eingefügt werden, um das Ergebnis dann im Browser zu sehen.

    HTML Template Tag

    Mit dem template-Element können wir in HTML Vorlagen erstellen, die wir dann über JavaScript manipulieren und nutzen können. Das template-Element wird von HTML-Browsern geparst und in dem DOM-Tree aufgenommen, aber nicht auf der Seite gerendert.

    Zunächst brauchen wir ein template, das wir in unserer HTML-Datei an beliebiger Stelle einfügen können.

    In diesem Fall ist es nur ein li-Element, das wir gleich in eine Liste einbauen möchten. Hierzu brauchen wir in derselben HTML-Datei noch eine leere Liste:

    Nun zum JavaScript: Da Web Components noch in Entwicklung sind, prüfen wir zunächst, ob HTML Templates im aktuellen Browser überhaupt unterstützt werden (1). Hier wird geprüft, ob man ein template-Element anlegen könnte und dieses das Property content hat. Ansonsten fügen wir einen Text ein, der uns über den fehlenden Support informiert (2). Diese Technik nennt sich Progressive Enhancement und soll sicherstellen, dass möglichst jeder Nutzer eine Seite auch benutzen kann.

    Wenn wir HTML Templates nutzen können, definieren wir eine Liste von Strings, die wir als li-Element in der Liste sehen möchten. Danach greifen wir über die DOM API auf das Template zu (1) und suchen uns innerhalb des Templates das li-Element (2). Die Liste benötigen wir, um die generierten li-Elemente einzufügen (3).

    Anschließend iterieren wir über die zuvor definierten Features und schreiben das jeweilige Feature in unser li-Element (4), klonen das Ganze (5) und fügen den Klon in die Liste ein (6)

    Zwischenfazit: Template Tags

    Wenn wir uns HTML Template Tags alleine ansehen, sind diese nicht sonderlich spektakulär: Nichts, was man nicht mit ein paar Zeilen JavaScript auch vorher schon in ähnlicher Form machen konnte. Wahrscheinlich blähen sie den HTML-Code auf und bieten wenig Mehrwert. Neu ist das Element template, das wir im HTML verwenden und dann über JavaScript manipulieren können. Trotzdem sollten wir sie nicht direkt abschreiben: Wir werden später noch sehen, dass wir sie in Kombination mit den anderen Features gut gebrauchen können.

    Momentan unterstützen Chrome, Edge, Firefox und Safari HTML Templates. Im Internet Explorer fehlt der Support. Insgesamt werden bei ca 89 % der Nutzer HTML Templates unterstützt.

    ChromeFirefoxSafariEdge
    jajajaja

    HTML Imports

    Die Idee bei HTML Imports ist es, HTML-Code auszulagern und über das link-Element in die Anwendung zu laden. Wir integrieren mit etwas JavaScript die importieren Daten in unsere Anwendung.

    Zunächst brauchen wir hier eine HTML-Datei, die den zu importierenden Code enthält.

    In unserer eigentlichen Seite müssen wir nun nur noch die zu importierende Datei über ein link-Element referenzieren.

    Im JavaScript-Code können wir nun erneut prüfen, ob der aktuelle Browser HTML Imports unterstützt:

    Jetzt können wir den Inhalt des Imports über JavaScript laden (1), das Element aus dem Import suchen, das wir gerne nutzen möchten (2) und in unsere HTML-Datei (hier direkt im body-Element) einfügen (3).

    Zwischenfazit: HTML Imports

    Natürlich können wir hier, ähnlich dem vorherigen Beispiel, das HTML manipulieren (das wäre allerdings nichts neues). HTML Imports entfernen so die zusätzlichen template-Tags in unserem Dokument und sorgen so für eine kleinere HTML-Datei. Zusätzlich wird durch das Auslagern die Wiederverwendung in anderen Dateien möglich. Leider kommt dieses Feature nicht kostenlos, da wir nun für jeden Import einen zusätzlichen Server Request haben. Dies bedeutet dann, dass wir Dinge wie Caching und CORS berücksichtigen müssen.

    HTML Imports sind momentan nur in Chrome implementiert und somit bei ca. 69 % der Nutzer verfügbar. Mozilla plant momentan nicht, HTML Imports zu implementieren.

    ChromeFirefoxSafariEdge
    janicht geplantnicht geplantin Diskussion

    Shadow DOM

    Das Shadow DOM erlaubt uns, innerhalb von HTML-Elementen ein eigenes DOM zu implementieren und dort zum Beispiel zusätzliche HTML Komponenten samt Styling zu hinterlegen. Dieses Shadow DOM ist unabhängig vom DOM, was die Entwicklung von Komponenten natürlich enorm vereinfacht. Gerade das Styling wird so vereinfacht, da sich CSS-Regeln nicht gegenseitig beeinflussen.

    Unser HTML ist hier etwas einfacher: Wir brauchen nur ein Element, in das wir unser Shadow DOM einfügen. Dies erinnert an die etablierten Frameworks, die ebenfalls nur einen Einstiegspunkt brauchen. Das p-Element unter dem div dient als Beispiel für das Styling innerhalb des Shadow DOM

    Wie bei den anderen Beispielen müssen wir überprüfen, ob wir das Shadow DOM im aktuellen Browser nutzen können.

    Jetzt können wir das Element, in dem wir das Shadow DOM anlegen möchten, auswählen und mit attachShadow() unser Shadow DOM erzeugen (1). Mit mode:"open" (2) wird die Manipulation des Shadow DOM durch andere JavaScript-Funktionen erlaubt. Wenn hier mode:"closed" genutzt wird, ist dies nicht möglich. Ein einfacher Anwendungsfall ist z. B., mithilfe von innerHTML zusätzliches HTML in unser Shadow DOM zu schreiben (3). Dies funktioniert nicht bei allen Elementen, weshalb wir hier statt einer Liste ein paar Absätze in das Shadow DOM einfügen. Das CSS, das ebenfalls hinzugefügt wird (4), wirkt sich nur auf die Element im Shadow DOM aus.

    Zwischenfazit: Shadow DOM

    Dies ist ein sehr grundlegendes Beispiel für das Shadow DOM. Schön ist, dass man mit relativ wenig Code ein eigenes DOM erstellen und HTML-Code dynamisch ergänzen kann, das unabhängig gestylt werden kann. Der ursprüngliche HTML-Code spiegelt diese Änderungen jedoch nicht wider und so ist auf den ersten Blick nicht ersichtlich, woher die Inhalte der Seite kommen.

    Das Shadow DOM ist momentan in Chrome und Firefox vollständig und in Safari teilweise implementiert, so dass hier ca 79 % der Nutzer das Feature nutzen können.

    ChromeFirefoxSafariEdge
    jain Entwicklung (nä. Version)teilweisein Diskussion

    Custom Elements

    Custom Elements erlauben es, eigene HTML-Tags zu schreiben und diese direkt im HTML-Dokument zu verwenden.

    Im einfachsten Fall könnte es so aussehen, dass wir im HTML-Code zunächst unser Custom Element einbinden:

    Um zu überprüfen, ob wir Custom Elements nutzen können, gibt es die folgende Prüfung:

    Nun können wir uns eine JavaScript-Klasse erzeugen (diese erbt von HTMLElement) (1) und definieren über innerHTML (2), wie das Markup der Komponente aussieht. Wichtig: der super-Konstruktor muss aufgerufen werden, damit alles funktioniert.

    Am Ende registrieren wir unsere Komponente als <web-components> (3). Custom Elements müssen übrigens unbedingt einen Dash (-) im Namen haben um zu funktionieren.

    Spannend sind die Methoden, die wir in einem Custom-Element nutzen können (Tabelle 1).

    APIBeschreibung
    static get observedAttributes()Funktion, die einen Array der Attribute zurückgibt, die überwacht werden sollen.
    connectedCallback()Diese Funktion wird immer aufgerufen, wenn dieses Element in das DOM eingefügt wird.
    disconnectedCallback()Diese Funktion wird immer aufgerufen, wenn dieses Element aus dem DOM entfernt wird.
    attributeChangedCallback(attrName, oldVal, newVal)Wird aufgerufen, wenn eines der überwachten Attribute verändert wird (bspw. durch ein Event).
    adoptedCallback()Wird aufgerufen, wenn das Element in ein anderes DOM verschoben wird.

    Zwischenfazit: Custom Elements

    Da wir Custom Elements in unserer Anwendung direkt im HTML-Code verwenden, können wir diese einfacher als React und Co integrieren. Die Browserkompatibilität ist allerdings, ohne Polyfill, ein Problem.

    Custom Elements sind in Chrome vollständig und in Safari teilweise implementiert. Im Firefox wird das Feature in der nächsten Version implementiert sein. Wir kommen damit auf eine Verbreitung von ca 79 %.

    ChromeFirefoxSafariEdge
    jain Entwicklung (nä. Version)jain Diskussion

    Shadow DOM, HTML Templates und Custom Elements

    Die vorherigen Beispiele zeigen, wie die einzelnen Features jeweils funktionieren. Erst die Kombination der einzelnen Features macht Web Components möglich: Wir erstellen ein Template (1) und verwenden dieses über ein Shadow DOM (2) in unserem Custom Element(3).

    Fazit

    Zusammenfassend lässt sich sagen, dass die hier vorgestellten Technologien noch nicht ohne den Einsatz von Polyfills im Projekt eingesetzt werden können. Mit fast 70 % Verbreitung ist allerdings auch schon ein guter Teil des Marktes abgedeckt. Sobald die Browserhersteller hier nachziehen, sollte einem Einsatz nichts mehr im Wege stehen.

    Bei den hier vorgestellten Features handelt es sich um Low-level-APIs, die nur als Fundament für andere Frameworks und Libraries dienen können. Denkbar ist, dass React irgendwann auf Web Components wechselt, oder, wie beispielsweise Vue.js und Angular schon heute, Bibliotheken anbietet, mit denen Web Components erzeugt werden können (vue-web-component-wrapper, angular elements). Vielversprechend sind hier auch Frameworks wie stencil.js oder Polymer, die die Nutzung von Web Components vereinfachen.

    Die Codebeispiele sind auch auf GitHub einsehbar.

    Eine erste Fassung des Artikels ist im Softwerker Vol. 11 erschienen. Jetzt kostenlos herunterladen.

Daniel Mies

Daniel ist als Software Crafter seit 2015 Teil des codecentric Teams. Er ist sowohl im Backend als auch im Frontend unterwegs.

Momentan konzentriert er sich auf die Themen IoT und Industrie4.0 und unterstützt Unternehmen als Product Owner bei der Umsetzung ihrer Projekte.

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.