(Bild: Diki Prayogo/ Shutterstock.com)
Die einen lieben HTMX, die anderen hassen es. Was ist dran am Hype um HTMX, was spricht für und was gegen die Bibliothek?
Eine Frage wird mir derzeit täglich gestellt. Von der Community, von Kunden, per E-Mail, telefonisch, auf Discord, in den Kommentaren und in persönlichen Gesprächen, um nur einige Beispiele zu nennen. Seit meinem kürzlich veröffentlichten Beitrag Vanilla Web: Der Frontend-Trend 2024? [1] hat das Interesse noch einmal spürbar zugenommen. Die Frage lautet: "Was ist Ihre Meinung zu HTMX?"
Diese Frage versuche ich aus meiner persönlichen Sicht umfassend und fundiert zu beantworten. Und falls Sie – was unwahrscheinlich, aber möglich ist – noch nie von HTMX gehört haben sollten: Lesen Sie diesen Blogeintrag dennoch. Ich bin überzeugt, dass auch in Ihrem Team früher oder später die Frage aufkommen wird: "Sollten wir uns nicht einmal HTMX genauer anschauen?" Damit Sie nicht völlig unvorbereitet sind, sondern bereits eine grobe Vorstellung haben, worum es bei HTMX geht, und um vielleicht auch das eine oder andere Argument parat zu haben, empfehle ich Ihnen die Lektüre der folgenden Zeilen.
HTMX ist eine kompakte Bibliothek für Web-Benutzeroberflächen und trug ursprünglich den Namen Intercooler.js. Mit der Einführung der Version 2 erfolgte die Umbenennung in HTMX [2], sodass HTMX 1.0 im Grunde Intercooler 2.0 entspricht. Der wesentliche Unterschied ist, dass sich HTMX als eine Neuentwicklung betrachten lässt, die – im Gegensatz zu Intercooler – nicht auf jQuery basiert. HTMX schlägt diesbezüglich einen neuen Weg ein.
Auf npm verzeichnet HTMX derzeit etwa 50.000 Downloads pro Woche. Zur Einordnung: Svelte erreicht knapp eine Million Downloads, Vue fast fünf Millionen und React über 20 Millionen. Warum HTMX dennoch keine Nischentechnik ist, werden wir später noch erläutern. Bis dahin ist es ratsam, bei der Interpretation der Download-Statistiken von HTMX auf npm eine gewisse Vorsicht walten zu lassen.
Was zeichnet HTMX im Vergleich zu anderen Technologien wie beispielsweise React aus? Der grundlegende Unterschied liegt in der Herangehensweise: HTMX setzt darauf, Web-Benutzeroberflächen weiterhin in HTML zu definieren, anstatt in JavaScript, wie es beispielsweise bei React der Fall ist. HTMX verfolgt eine HTML-zentrierte Architektur, im Gegensatz zu vielen anderen Bibliotheken und Frameworks, die sich auf JavaScript konzentrieren. Sie arbeiten also mit regulärem HTML und erweitern es durch spezielle, von HTMX definierte Attribute. Auf diese Weise lassen sich viele Standardaufgaben, für die sonst JavaScript erforderlich wäre, vollständig deklarativ in HTML realisieren.
Einige Entwicklerinnen und Entwickler betrachten diesen Ansatz als etwas völlig Neuartiges. Doch in Wahrheit ist das Konzept nicht neu. Ähnliche Ansätze gab es bereits in der Vergangenheit, wie zum Beispiel bei Knockout.js [4] im Jahr 2010. Auch Angular 1, die ursprüngliche Version von Angular, folgte diesem Prinzip im Jahr 2013. Interessanterweise stammt Intercooler, der Vorläufer von HTMX, ebenfalls aus dem Jahr 2013. Somit greift HTMX eine Denkweise auf, die etwa ein Jahrzehnt alt ist. Da viele Entwicklerinnen und Entwickler diese Phase entweder nicht selbst miterlebt oder sie schlicht vergessen haben, erscheint der Ansatz, HTML in den Vordergrund zu rücken und deklarativ zu erweitern, einigen nun als radikal anders und neuartig, obwohl er das faktisch nicht ist.
HTMX funktioniert im Kern durch den Einsatz benutzerdefinierter Attribute. Um ein einfaches Beispiel anzuführen: Stellen Sie sich ein div-Element vor, dem Sie das Attribut hx-post hinzufügen, konkret hx-post="/articles". Normalerweise würde der Browser dieses Attribut ignorieren, da er unbekannte HTML-Elemente und -Attribute üblicherweise nicht beachtet. HTMX jedoch belebt dieses Attribut: Wenn Sie auf das div klicken, wird dank HTMX im Hintergrund eine HTTP-POST-Anfrage an die URL /articles gesendet. Auf diese Weise kann jedes beliebige HTML-Element einen POST-Request auslösen, wobei dies meist durch Klicken geschieht. Bei Formularen wird ein Request üblicherweise durch das Absenden ausgelöst. So lässt sich jedes Element zur Interaktion mit dem Netzwerk nutzen. Diese Funktionalität beschränkt sich nicht nur auf POST-Requests, sondern umfasst auch GET, PUT und DELETE. Demnach kann jedes HTML-Element jede Art von HTTP-Request initiieren.
Nun stellt sich die Frage, was mit dem Ergebnis, also der vom Server zurückgesendeten Antwort, geschieht. HTMX fängt diese ab und setzt, um bei dem div-Beispiel zu bleiben, das Ergebnis als neuen Inhalt dieses div-Elements ein. Somit wird die Serverantwort direkt angezeigt. Optional kann das Ergebnis auch in einem anderen Element dargestellt werden. Hierfür verwendet man zusätzlich das Attribut hx-target und gibt als Wert einen CSS-Selektor an, der das Element bestimmt, in dem das Ergebnis erscheinen soll. Mit anderen Worten, HTMX ermöglicht es, mit nur zwei Attributen einen AJAX-Request auszuführen, ohne auch nur eine einzige Zeile JavaScript schreiben zu müssen.
Es ist auch möglich, das gesamte Element komplett zu ersetzen: Geben Sie einfach das hx-swap-Attribut an. Damit können Sie auswählen, wie das Ergebnis gerendert werden soll: als Inner- oder als Outer-HTML, vor dem bestehenden Inhalt, nach dem bestehenden Inhalt, gar nicht und so weiter. Allein diese wenigen Attribute machen HTMX bereits äußerst flexibel in der Anwendung.
Es wäre natürlich praktisch, während des Ladeprozesses einen Ladeindikator angezeigt zu bekommen. Tatsächlich ermöglicht HTMX, jedes beliebige Element als Ladeindikator zu definieren. Wünschen Sie sich eine Animation beim Einblenden des neuen Inhalts? Auch das ist mit HTMX kein Problem, da es entsprechende Animationen unterstützt. Soll die Kommunikation nicht über einen einmaligen HTTP-Request ablaufen, sondern periodisch, um beispielsweise Daten zu aktualisieren, also über Polling? Auch das ist mit HTMX machbar, indem Sie ein Zeitintervall festlegen. Bevorzugen Sie eine Push-Kommunikation? HTMX ermöglicht ebenfalls, WebSockets zu nutzen. Alternativ können Sie auf Server-Sent Events (SSE) zurückgreifen, die mit HTML5 eingeführt wurden. Und das ist nur ein Ausschnitt der Möglichkeiten. Für viele Standardanwendungen müssen Sie kein JavaScript mehr schreiben, sondern fügen lediglich ein paar Attribute in Ihr HTML ein, und HTMX erledigt den Rest im Hintergrund.
Übrigens, HTMX funktioniert dabei auch vollständig ohne npm. Es reicht aus, ein Script-Tag in Ihr HTML einzufügen und HTMX von einem Content Delivery Network (CDN) zu laden. Dabei beträgt die Größe lediglich etwa 14 KByte. Das System ist sogar mit dem Internet Explorer kompatibel, um nur einige Vorteile zu nennen. Es wird Ihnen also wirklich leicht gemacht, HTMX zu verwenden. Die Tatsache, dass sich HTMX einfach über ein CDN einbinden lässt, ist auch der Grund, warum ich zuvor erwähnte, dass die Download-Statistiken von npm mit Vorsicht zu betrachten sind. Denn diese spiegeln lediglich wider, wie oft HTMX über npm heruntergeladen wurde, nicht aber, wie oft es von einem CDN geladen oder möglicherweise direkt in Webseiten eingebettet wird – so wie es vor zehn Jahren üblich war. Daher ist es schwierig, die tatsächliche Verbreitung von HTMX zu ermitteln.
Allerdings dürfte die Verbreitung bei Weitem nicht so groß sein, wie die Menge an Fragen, die ich derzeit dazu erhalte, vermuten lässt. Es gibt einen gewissen Hype um HTMX, der aber eher kurz und überschaubar bleiben dürfte. Wie lange er anhalten und wie nachhaltig er sein wird, muss sich noch zeigen.
Wenn das Ergebnis eines HTTP-Requests direkt als Inner-HTML gerendert wird, wie verhält es sich dann mit APIs? Schließlich muss aus dem JSON, XML oder einem anderen Datenformat, das eine API liefert, etwas entstehen, das in HTML darstellbar ist. Es müsste also eine Art Templating oder Ähnliches geben, oder? Doch das ist nicht der vorgesehene Weg. Tatsächlich ist es so, dass der Server fertige HTML-Fragmente liefern muss. Zugegebenermaßen gibt es Plug-ins für HTMX, um unter anderem auch JSON verarbeiten zu können, allerdings macht die Dokumentation klar deutlich, welcher Stellenwert diesem Ansatz zugedacht wird – nämlich ein äußerst geringer.
Das bedeutet, HTMX arbeitet im Kern nicht mit einer klassischen API zusammen, sondern der Server muss speziell für HTMX um Routen erweitert werden, die fertiges HTML zurückgeben. Folglich hebt HTMX die Trennung von Präsentation und Daten auf – es sei denn, man entwickelt ein dediziertes Backend für HTMX. Das entspräche dem Ansatz des BFF-Patterns (Backend For Frontend), bedeutet aber zugleich auch zusätzlichen Aufwand.
Optional ist es übrigens möglich, dass der Server komplette Seiten zurückgibt und HTMX clientseitig mittels eines Attributs angewiesen wird, nur einen Ausschnitt dieser Seite zu rendern. Das sichert Kompatibilität zu Backends, die vollständig serverseitig rendern. Allerdings ist das ziemlich ineffizient, da bei jedem Aufruf zunächst eine komplette Seite geladen werden muss, von der dann möglicherweise der Großteil umgehend wieder verworfen wird. HTMX arbeitet demnach ausschließlich mit HTML und nicht mit herkömmlichen APIs.
Damit komme ich zu meinem ersten Kritikpunkt: Dieser Ansatz verlangt, dass ich als Entwicklerin oder Entwickler das Backend an das Frontend anpassen muss. Aus meiner Sicht ist das eine eher schlechte Praxis, die man vermeiden sollte, sofern es keine wirklich guten Gründe dafür gibt. Es verletzt eine grundlegende Regel der Softwarearchitektur, nach der Abhängigkeiten stets von oben nach unten verlaufen sollten und nicht umgekehrt. Denn dadurch wird Ihr Backend faktisch an Ihr Frontend gebunden. Noch problematischer ist, dass Ihr Backend an die spezifische Wahl einer UI-Technologie gekoppelt wird, was grundsätzlich keine gute Idee ist.
An dieser Stelle führen HTMX-Anhängerinnen und -Anhänger häufig das erwähnte BFF-Pattern (Backend For Frontend) an. Folgt man diesem Pattern, ist eine spezielle API für ein konkretes Frontend kein schlechter, sondern vielmehr sogar ein erstrebenswerter Ansatz. Ich sehe das zwiegespalten. Prinzipiell spricht nichts gegen das BFF-Pattern. Aber ich finde den Gedanken seltsam, ein zusätzliches Backend zu entwickeln, um eine Frontend-Bibliothek nutzen zu können, die vor allem damit beworben wird, dass alles so einfach sei und man kaum noch programmieren müsse. Tatsächlich verlagert das Pattern viel Aufwand und Komplexität in das Backend. Das ist legitim, aber damit ist es eben nicht mehr so einfach, HTMX "mal eben" zu verwenden – wie die Befürworter gerne implizieren.
Hinzu kommt, dass Sie um eine JSON-basierte API vermutlich kaum herumkommen werden, wenn Sie zusätzlich beispielsweise auch noch eine Mobile-App, eine Desktop-Anwendung oder andere Dienste anbinden möchten. Das missfällt mir. Da ich erwähnte, dass das Backend an HTMX als spezifische Technologie gebunden wird: HTMX erwartet in bestimmten Situationen spezielle, nicht standardisierte HTTP-Statuscodes, wie zum Beispiel den Statuscode 286, der HTMX-eigen ist. Sie werden diesen Statuscode nirgendwo anders finden oder nutzen können, was einfach keine gute Idee ist.
HTMX zwingt Sie zudem dazu, sich eine weitere framework- oder bibliotheksspezifische, proprietäre Syntax aneignen zu müssen. Die von HTMX eingeführten Attribute und deren Wertestrukturen folgen nämlich ebenfalls keinem Standard. Das ist im Grunde das Gleiche, was bereits bei Technologien wie Knockout oder Angular 1 der Fall war. Wenn Sie in der Vergangenheit mit einer dieser Technologien gearbeitet haben, könnten Sie sich fragen: Hat Ihnen das Erlernen der spezifischen HTML-Attribute von Knockout oder Angular auf lange Sicht einen Nutzen gebracht? Können Sie das damals erworbene Wissen heute überhaupt noch nutzen?
Wenn nicht, warum sollte es mit der HTMX-spezifischen Syntax in ein paar Jahren anders sein? Kurz gesagt: Wenn HTMX nicht zum langfristigen Standard wird, investieren Sie Zeit und Mühe in etwas, das schon heute absehbar morgen überflüssig sein wird. Ich weiß nicht, wie Sie dazu stehen, aber auf mich wirkt das wenig ansprechend.
Zu den bereits genannten Punkten kommt hinzu, dass Sie mit den hx-Attributen technisch gesehen ungültiges HTML schreiben. Wenn Sie eine mit HTMX erstellte Webseite durch einen Validator laufen lassen, werden Sie zahlreiche Fehlermeldungen erhalten. Ich behaupte, dass beispielsweise Google es nicht besonders schätzt, wenn Webseiten offensichtlich kein syntaktisch valides HTML verwenden, was sich möglicherweise negativ auf das Suchmaschinenranking auswirken könnte. Technisch gesehen handelt es sich um Data-Attribute: Sie könnten also beispielsweise hx-post in data-hx-post umwandeln, um syntaktisch valides HTML zu erhalten. Aber wer tut das schon, insbesondere da auch die Dokumentation von HTMX und sämtliche Beispiele hier mit schlechtem Vorbild vorangehen?
Ferner sind Sie mit dem Problem der fehlenden Typsicherheit konfrontiert. Ein einziger Tippfehler genügt, Ihre Webseite lahmzulegen, woraufhin Sie manuell mit der Fehlersuche beginnen müssen. Das erinnert stark an die Erfahrungen mit Knockout: Ein Fehler im Data-Binding und nichts funktionierte mehr. Aber man erhielt auch keine Fehlermeldung, sondern nur eine nicht funktionierende Webseite. Sie können sich sicherlich vorstellen, wie wenig Vergnügen die Fehlersuche in solchen Fällen bereitet. Effektives Debugging ist praktisch nicht möglich. Zudem bieten die gängigen Editoren und IDEs (noch) keine Unterstützung für diese Syntax, was bedeutet, dass Ihnen Funktionen wie IntelliSense fehlen. Zwar könnten entsprechende Plug-ins Abhilfe schaffen, doch das grundlegende Problem der mangelhaften Debugging-Erfahrung bleibt.
Mit viel Wohlwollen könnte man sagen, dass HTMX bestenfalls für sehr kleine Webseiten geeignet ist. Allerdings gibt es so viele Aspekte, die HTMX für größere, komplexere Projekte vollkommen ungeeignet machen: HTMX missachtet bewährte Architekturprinzipien, widerspricht gängigen Standards, missachtet die Trennung von UI und Daten und legt dem Backend Restriktionen auf, weil das Frontend es so verlangt. Es lässt sich nicht vernünftig debuggen oder testen.
Ich halte also nichts von HTMX. Aus meiner Perspektive ist es eine miserable Idee, auf HTMX zu setzen – es fühlt sich wie ein Rückschritt um zehn Jahre an.
Ich möchte damit nicht behaupten, dass React, Angular, Vue, Svelte oder irgendein anderes UI-Framework die unangefochtene Lösung für alles sei. Es gibt auch dort viele Kritikpunkte, die Frontend-Entwicklung ist insgesamt unnötig kompliziert geworden und es bedarf dringend einiger Veränderungen, um die Arbeit wieder spaßvoll und effizienter zu gestalten. Der Weg zu einer besseren Zukunft sollte jedoch über Standards führen und nicht über den nächsten proprietären Ansatz, der uns dazu verführt, uns erneut auf ein Framework zu verlassen, das in zehn Jahren niemand mehr kennt oder verwendet. Und wir sollten uns sicherlich nicht auf eine Lösung einlassen, die dieselben Fehler wiederholt, die wir bereits vor zehn Jahren gemacht haben. HTMX gehört zu den letzten Technologien, zu deren Einsatz ich raten würde.
Der richtige Ansatz besteht meiner Meinung nach darin, uns von der Notwendigkeit eines Frameworks oder einer Bibliothek zu lösen und stattdessen stärker auf Standards und native Web-Technologien zu setzen. Denn nur so können wir der Abhängigkeitsfalle entkommen. Wie genau dieser Weg aussehen wird, weiß auch ich noch nicht. Aber dass dies der Weg ist, den wir einschlagen sollten, davon bin ich überzeugt. In dieser Hinsicht hat sich bereits einiges getan. – wie ich in meinem Blogeintrag Vanilla-Web: Der Frontend-Trend 2024? [5] ausgeführt habe.
Trotz aller ausgeführten Argumente kann es natürlich sein, dass Sie oder Ihr Team dennoch überzeugt sind, dass HTMX für Ihren speziellen Anwendungsfall geeignet sein könnte. In diesem Fall bitte ich Sie um einen Gefallen: Lassen Sie uns darüber sprechen, nehmen Sie Kontakt mit uns (www.thenativeweb.io) [6] auf. Vielleicht stellen wir gemeinsam fest, dass HTMX tatsächlich in Ihrem speziellen Fall sinnvoll ist.
URL dieses Artikels:
https://www.heise.de/-9633960
Links in diesem Artikel:
[1] https://www.heise.de/blog/Vanilla-Web-Der-Frontend-Trend-2024-9611002.html
[2] https://htmx.org/
[3] https://www.heise.de/Datenschutzerklaerung-der-Heise-Medien-GmbH-Co-KG-4860.html
[4] https://www.heise.de/hintergrund/Model-View-ViewModel-mit-Knockout-js-1928690.html
[5] https://www.heise.de/blog/Vanilla-Web-Der-Frontend-Trend-2024-9611002.html
[6] https://www.thenativeweb.io/
[7] mailto:map@ix.de
Copyright © 2024 Heise Medien
(Bild: FotoDuets/Shutterstock.com)
Die Entwicklung von Web-UIs erfordert zu viele Frameworks und Tools, die zudem aufwendig und komplex zu integrieren sind. Könnte sich das im Jahr 2024 ändern?
Stellen Sie sich vor, Sie planen die Entwicklung einer neuen Web- oder Cloud-basierten Anwendung. Dabei haben Sie für das Backend bereits alle Technologien festgelegt, doch bei der Auswahl für das Frontend herrscht noch Unsicherheit: Sollten Sie auf bewährte Frameworks wie React, Angular oder Vue setzen, oder wäre ein jüngeres, weniger etabliertes Framework wie Svelte oder Solid.js die bessere Wahl?
Diese Frage ist keineswegs neu, und es gibt keine eindeutige Antwort. Doch unabhängig von Ihrer Entscheidung gehen Sie stets eine Bindung ein, was einen sogenannten "Vendor-Lock-in" zur Folge hat, ohne die Garantie, dass das gewählte Framework auch in Zukunft noch unterstützt wird.
Darüber hinaus gibt es immer noch keinen allgemeingültig etablierten Ansatz für die Web-UI-Entwicklung, was die regelmäßige Veröffentlichung neuer Frameworks belegt. Zusätzlich zur Framework-Auswahl benötigen Sie allerdings auch noch eine Vielzahl von Werkzeugen: vom TypeScript-Compiler über SASS- oder LESS-Precompiler bis hin zu Package-Managern wie npm oder Yarn, Build-Tools wie Vite und eventuell speziellen Bundlern. Viele Entwicklerinnen und Entwickler verlieren angesichts dieser stetig wachsenden Komplexität und der Flut neuer Tools die Freude an der Webentwicklung, deren Merkmal vor vielen Jahren einmal Einfachheit und Leichtigkeit waren.
Angesichts dieser Entwicklung stellt sich die Frage, wohin der Trend führt und ob es nicht an der Zeit ist, innezuhalten und zu überlegen, ob die Branche möglicherweise seit Jahren in die falsche Richtung läuft. Gibt es vielleicht einen Weg, die Dinge grundlegend zu verbessern?
Tatsächlich war die Webentwicklung früher grundlegend anders als heute: Sie war unkompliziert und direkt. Ein einfacher Texteditor, ein paar Änderungen an HTML, CSS oder JavaScript und ein Speichern und Neuladen im Browser genügten, ohne jegliche Notwendigkeit für Compiler oder spezielle Werkzeuge. Diese Einfachheit, die vor etwa 25 Jahren bestand, stand im starken Kontrast zur damaligen Desktop-Entwicklung, die praktisch immer einen Compiler erforderte und dadurch Wartezeiten bis zur Ausführung mit sich brachte. Diese reduzierte und unmittelbare Art der Webentwicklung war faszinierend und stellte einen ihrer größten Reize dar.
Heute hat sich das Bild jedoch gewandelt. Die Entwicklung ist nicht mehr so intuitiv. Für das Schreiben von HTML ist beispielsweise oft JSX oder eine ähnliche Abstraktion erforderlich, was wiederum einen Precompiler voraussetzt. Dieser muss über npm installiert werden, wofür Node.js notwendig ist, das idealerweise über den Node Version Manager (nvm) installiert wird. Bereits diese Kette aus Technologien, die lediglich für das Schreiben von HTML benötigt wird, verdeutlicht die Komplexität. Nicht einmal berücksichtigt sind hierbei CSS oder JavaScript, geschweige denn das umfassende Ökosystem mit Tools für Linting, Formatting und weiteren Funktionen. Kurz gesagt: Die Freude an der Frontend-Webentwicklung ist durch diese Komplexitätssteigerung merklich gesunken.
Das Bedauerliche an der heutigen Webentwicklung ist, dass viele der verwendeten Praktiken und Tools eigentlich gar nicht mehr zwingend notwendig wären, da moderne Webbrowser inzwischen eine Vielzahl von Funktionen nativ unterstützen. Im Laufe der Jahre haben wir den eigentlichen Zweck hinter der Nutzung all dieser Frameworks und Werkzeuge jedoch aus den Augen verloren. Es hat sich eine Gewohnheit etabliert, bei der stets die Eignung des eingesetzten Tools hinterfragt wird, ohne je zu überprüfen, ob ein Werkzeug an sich noch erforderlich ist.
Doch zumindest mir scheint es so, als könnte sich das im Jahr 2024 allmählich ändern. Es zeichnet sich ein Momentum ab, das darauf hindeutet, dass die Webentwicklung als solche in den nächsten zwölf Monaten eine grundlegende Wandlung erfahren könnte. Das Ergebnis könnte ein wesentlich stabilerer und zuverlässiger Technologie-Stack sein, der uns langfristig begleiten wird. Im Folgenden möchte ich daher einen Ausblick darauf geben, wie diese Entwicklung aussehen könnte.
Wenn man Entwicklerinnen und Entwickler nach dem Hauptgrund für die Nutzung von Frameworks wie React oder Angular fragt, beschreibt die am häufigsten gegebene Antwort die Möglichkeit, eigene Komponenten definieren und orchestrieren zu können. Dabei geht es um das Erstellen autonomer, in sich geschlossener und insbesondere wiederverwendbarer Codeeinheiten, die modular zu einer umfassenderen Einheit, sei es eine Webseite oder eine Webanwendung, zusammengesetzt werden können. Das Wesentliche dabei ist, dass das Orchestrieren dieser Elemente eigentlich eine Grundfunktion von HTML darstellt – es bedürfte also lediglich einer Methode zur Definition eigener HTML-Elemente, um die nativen Möglichkeiten von HTML um benutzerdefinierte Komponenten zu erweitern.
Genau hier kommen die sogenannten Custom Elements [2] ins Spiel. Ein Custom Element ist ein durch JavaScript definiertes, eigenständiges HTML-Element, das anschließend wie jedes standardmäßige HTML-Element genutzt werden kann. Das bedeutet, dass zur Erstellung wiederverwendbarer HTML-Komponenten grundsätzlich kein spezielles Framework erforderlich ist: HTML selbst bietet bereits diese Flexibilität.
Nun könnte der Einwand erhoben werden, dass HTML allein nicht ausreiche, da Komponenten in der Regel auch individuell gestaltet werden sollen. Dabei ist es oft ein Anliegen, sicherzustellen, dass die Stile verschiedener Komponenten sich nicht gegenseitig beeinflussen. Mit anderen Worten: Man wünscht sich für jede Komponente einen eigenen, klar abgegrenzten Bereich für CSS. In vielen Frameworks hat sich dafür das Konzept der CSS-Module durchgesetzt. Dies erfordert jedoch in der Regel einen Bundler, der diese CSS-Module auch entsprechend unterstützt.
Doch auch hier ist eine solche Komplexität nicht zwingend erforderlich, da Webbrowser nativ in der Lage sind, eigene CSS-Bereiche zu verwalten. Dies ermöglicht es, jedem Custom Element einen abgeschotteten CSS-Bereich zuzuweisen, was durch die Verwendung des Shadow DOM [3] erreicht wird. Die Kombination aus Custom Elements und dem Shadow DOM bildet die Grundlage für das, was gemeinhin als Web Components bekannt ist. Streng genommen gehört dazu auch das HTML-Template-Element [4], aber im Kern erlauben Web Components genau das, wofür häufig zusätzliche Frameworks eingesetzt werden: das Definieren von wiederverwendbaren Komponenten mit einem eigenen CSS-Bereich.
Man könnte nun argumentieren, dass Web Components, obwohl sie bereits seit 2011 existieren und durchaus ihre Vorzüge haben, in der Praxis oft wenig Freude bereiten, da ihre APIs als altbacken empfunden werden können. Ich stimme dieser Ansicht vollkommen zu. Glücklicherweise existieren jedoch elegante Abstraktionen für Web Components, die ihre Nutzung erheblich erleichtern. Ein Beispiel hierfür ist das Framework Lit [5].
Hier könnte der Einwand folgen, dass die Verwendung solcher Abstraktionen dem eigentlichen Zweck zuwiderläuft, da man dadurch wieder auf ein Framework angewiesen ist. Das ist grundsätzlich korrekt, doch im Gegensatz zu Frameworks wie React oder Angular erzeugt man mit Lit Komponenten, die nicht an ein spezifisches Framework gebunden sind. Diese Komponenten sind universell einsetzbar, egal ob mit anderen Frameworks oder ganz ohne. Dieser Aspekt stellt für mich persönlich eine deutliche Verbesserung dar.
Zu Beginn habe ich meine Vorbehalte gegenüber dem Build-Schritt in der Entwicklung erwähnt. Die Annahme, dass die Nutzung von Lit als Framework zwangsläufig einen solchen Schritt nach sich zieht, hielt ich lange für gegeben. Doch diese Annahme ist nicht korrekt: Lit kann bei Bedarf tatsächlich vollständig zur Laufzeit ausgeführt werden, ohne die Notwendigkeit eines Compilers, was den Entwicklungsprozess erheblich vereinfacht. Noch bequemer wird es, wenn man erkennt, dass Lit nicht einmal über npm installiert werden muss, sondern direkt über einen Import aus einem Content Delivery Network (CDN) eingebunden werden kann.
Gegen den Einwand, dass dies zu einer Abhängigkeit von Versionsnummern in der Import-URL führen würde, gibt es eine elegante Lösung: das Verwenden einer Import Map [6]. Dieses weitere Feature moderner Browser ermöglicht es, einmalig und zentral zu definieren, dass es beispielsweise einen Import namens "lit" geben und auf welche URL dieser verweisen soll. Anschließend kann in jedem Skript mit Lit gearbeitet werden, als wäre es lokal via npm installiert. Damit ist das Problem gelöst – ganz ohne npm und ohne Build-Schritt.
Die Möglichkeit, JavaScript-Code als ES-Module dynamisch zur Laufzeit nachzuladen, hat in den letzten Jahren die Tür für flexiblere Entwicklungsansätze geöffnet. Ein häufiger Einwand hierbei ist die Befürchtung, dass die Anwendung letztlich aus vielen kleinen Dateien bestehen und dadurch unnötiger HTTP-Overhead beim Laden entstehen könnte. Ich erkenne diesen Punkt grundsätzlich an, doch stellt sich die Frage nach der tatsächlichen Relevanz dieses Overheads (insbesondere in Zeiten von HTTP/2). Ist für die Webseite oder die Webanwendung, an der gearbeitet wird, wirklich jede Millisekunde Ladezeit entscheidend, oder spielt dies eine untergeordnete Rolle?
Sicherlich gibt es Szenarien, beispielsweise im Bereich der Suchmaschinenoptimierung (SEO), bei denen eine schnelle Ladezeit mit möglichst wenigen Requests von großer Bedeutung sein kann. Andererseits existieren auch Fälle, in denen die Performance weniger kritisch ist, etwa bei Anwendungen, die nicht öffentlich zugänglich sind und nur einem begrenzten Nutzerkreis dienen. In solchen Situationen könnte der zusätzliche Overhead vernachlässigbar sein. Es lohnt sich, diese Aspekte zumindest einmal in Betracht zu ziehen und zu überdenken.
Bis zu diesem Punkt haben wir gesehen, dass es möglich ist, Komponenten zu definieren und zu orchestrieren, dies mit einer benutzerfreundlichen API zu tun, CSS zu scopen, eine zentrale Importverwaltung zu haben und all das ohne einen Compile- oder Build-Schritt zu benötigen. Doch was, wenn Sie CSS nicht direkt innerhalb einer Webkomponente definieren möchten? Nicht alle Entwicklerinnen und Entwickler bevorzugen es, HTML, CSS und JavaScript in einer einzigen Datei zu kombinieren. Viele ziehen es stattdessen vor, CSS in externe Dateien auszulagern, ein Ansatz, der einer der Vorzüge von CSS-Modules ist, und der dort anstandslos funktioniert.
Das Interessante ist, dass dies mit CSS Module Scripts [7] tatsächlich auch nativ möglich ist, ohne die Notwendigkeit von CSS-Modulen und dem entsprechenden Tooling (wobei dieses Feature derzeit nur von Chrome-basierten Webbrowsern unterstützt wird). Das Konstrukt stützt sich auf die sogenannten Constructable Stylesheets [8]. Denn in Kombination bieten diese beiden Technologien genau das, was viele sich wünschen: gescopetes CSS innerhalb eines Shadow DOM, jedoch in einer separaten CSS-Datei.
Bezüglich CSS könnte man sich fragen, ob der Einsatz von Präprozessoren wie SASS oder LESS wirklich notwendig ist. Oftmals wird als Hauptgrund für deren Verwendung die Fähigkeit genannt, CSS-Anweisungen verschachteln zu können. Interessanterweise bietet CSS mittlerweile jedoch native Unterstützung für das Nesting, wodurch eine der wesentlichen Funktionen, die bisher Präprozessoren vorbehalten war, direkt verfügbar wird. Dies macht den Einsatz solcher Tools weitgehend überflüssig.
Darüber hinaus sind viele weitere Features, die einst den Einsatz von SASS oder ähnlichen erforderlich machten, nun Teil des CSS-Standards, einschließlich, aber nicht beschränkt auf, das Theming. Letzteres lässt sich effektiv mit nativen CSS-Variablen bewerkstelligen, was den Bedarf an externen Präprozessoren weiter verringert.
Es ist klar, dass die native Webentwicklung nicht in jeder Hinsicht eine 1:1-Alternative zu Frameworks wie React oder Angular darstellt. Diese Frameworks geben schließlich auch eine gewisse Struktur für Anwendungen vor, die allerdings je nach Framework variieren kann. Dennoch ist es bemerkenswert, wie viel mittlerweile mit den nativen Funktionen von Webbrowsern erreicht werden kann, wodurch der Bedarf an Compilern, Bundlern und ähnlichen Tools entfällt oder zumindest deutlich reduziert wird. Der vollständige Verzicht wird gelegentlich als "Buildless" bezeichnet, was den Fokus allerdings zu sehr auf den Wegfall des Kompilierungsschrittes legt.
Ich persönlich würde es vorziehen, diesen Ansatz eher als "Vanilla-Web" zu bezeichnen, in Anlehnung an "Vanilla-JavaScript". Dies impliziert die Nutzung des Webs in seiner reinsten Form, ohne externe Bibliotheken und Frameworks, und stützt sich ausschließlich auf die standardmäßig verfügbaren Funktionen.
Möglicherweise ist alles bis hierhin beschriebene für Sie nichts oder zumindest kaum Neues, da viele der angesprochenen Technologien bereits seit einigen Jahren verfügbar sind. Der entscheidende Punkt ist jedoch, dass diese Technologien zwar existieren und greifbar sind, bislang aber nicht das Gefühl aufkommt, dass sie in größerem Maßstab effektiv kombiniert und im großen Stil eingesetzt werden. Stattdessen neigen viele Entwicklerinnen und Entwickler dazu, aus Gewohnheit bei den Frameworks zu bleiben, die ihnen vertraut sind.
Mein Eindruck ist jedoch, dass eine zunehmende Bereitschaft für Veränderungen in dieser Hinsicht entsteht. Natürlich würde eine solche Anpassung eine erneute Umstellung bedeuten, aber das Besondere daran wäre, dass es sich um die möglicherweise letzte Umstellung dieser Art handeln könnte. Dieser Ansatz könnte sich als zuverlässiger und nachhaltiger erweisen als einige der Web-UI-Frameworks, mit denen wir in den letzten Jahren konfrontiert waren.
Ein wesentlicher Faktor, der den Übergang zu einem vollständig Build-freien Entwicklungsprozess erschwert, ist der Einsatz von TypeScript. Zwar existiert der etwas unkonventionelle Vorschlag von Microsoft, Typ-Annotationen in TypeScript als Kommentare innerhalb von JavaScript zu behandeln [9], doch in der Praxis ist ein Compiler momentan noch unumgänglich. Dies muss zwar nicht zwingend der offizielle TypeScript-Compiler sein (Tools wie esbuild können diese Aufgabe ebenfalls übernehmen), aber ein Build-Schritt ist so oder so nach wie vor erforderlich.
Eine Alternative könnte darin bestehen, auf TypeScript-spezifische Typdefinitionen zu verzichten und stattdessen auf JSDoc sowie das manuelle Erstellen von .d.ts-Dateien zurückzugreifen. Das ermöglicht es, den TypeScript-Compiler zu umgehen und dennoch eine angemessene Typsicherheit zu gewährleisten. Das Svelte-Team ist ein prominenter Befürworter dieser Methode und hat für Svelte 4 die Implementierung dieses Ansatzes mit JSDoc umgesetzt. Es bleibt spannend zu beobachten, wie sich diese Entwicklung in der Praxis bewähren wird.
Für Sie bedeutet das vor allem, dass Ihr bevorzugtes JavaScript-Framework samt dem dazugehörigen Tooling möglicherweise nicht mehr so unverzichtbar ist, wie es in den vergangenen Jahren den Anschein hatte. Ich empfehle Ihnen daher, sich mit den erwähnten Technologien und Konzepten vertraut zu machen, eigene Experimente durchzuführen und kritisch zu hinterfragen, ob das von Ihnen genutzte Framework und Tooling tatsächlich den Mehrwert bietet, den Sie erwarten, oder ob es für bestimmte Aufgaben vielleicht überdimensioniert ist.
Ich vermute, dass sich im Laufe dieses Jahres in dieser Hinsicht einiges ändern könnte. Wenn Sie diesen Weg nicht allein beschreiten möchten, sondern Ihren Technologiestack gerne gemeinsam mit jemandem überprüfen und reflektieren möchten, können wir bei the native web [10] Sie dabei gerne unterstützen.
URL dieses Artikels:
https://www.heise.de/-9611002
Links in diesem Artikel:
[1] https://www.heise.de/Datenschutzerklaerung-der-Heise-Medien-GmbH-Co-KG-4860.html
[2] https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements
[3] https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM
[4] https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots
[5] https://lit.dev/
[6] https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap
[7] https://web.dev/articles/css-module-scripts
[8] https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet
[9] https://www.youtube.com/watch?v=7fNFbJDdDuA
[10] https://www.thenativeweb.io/
[11] mailto:rme@ix.de
Copyright © 2024 Heise Medien