- Der Webplattform fehlt derzeit eine deklarative Templating-API, die Entwickler dringend brauchen
- In den meisten modernen Web-Frameworks ist Templating eine Kerntechnik, aber in der Standard-DOM-API gibt es keine sichere und effiziente Methode, Templates zu erzeugen und zu aktualisieren
- Dadurch entstehen für Nutzer, Entwickler, Frameworks und sogar auf Plattformebene gleichermaßen Unannehmlichkeiten und Performance-Einbußen
- Jetzt ist der Zeitpunkt gekommen, eine Templating-API einzuführen, da sich in jüngster Zeit genügend Framework-Erfahrungen und JavaScript-Funktionen angesammelt haben, um Implementierung und Standardisierung praktikabler zu machen
- Unter Einbeziehung verschiedener Modelle wie Template-Identität und signalbasierter Reaktivität wird eine Richtung für die nächste Generation von Templating-APIs aufgezeigt
Zusammenfassung des Vorschlags
- Dieser Beitrag erläutert Hintergrund und Notwendigkeit des Vorschlags, der Webplattform eine deklarative Templating-API hinzuzufügen
- Die DOM-API ist mächtig, aber im Standard-DOM fehlt eine Templating-API, mit der sich mehrere Nodes auf Basis von Daten sicher definieren und effizient aktualisieren lassen
- Zentrale Frameworks wie React, Vue und Angular setzen alle deklaratives Templating als Kernprinzip ein und bieten damit Vorteile bei Produktivität, Sicherheit, Performance, statischer Analyse und Server-Side Rendering
- Durch das Fehlen einer Templating-API leiden Nutzer, Entwickler, Frameworks und die Plattform unter unnötiger Komplexität, Sicherheitsrisiken, Performance-Verlusten und höheren Einstiegshürden
- Der Text argumentiert, dass jetzt der richtige Zeitpunkt für die Einführung einer solchen API ist, und schlägt eine schrittweise Standardisierung auf Basis bestehender Framework-Erfahrungen und moderner JavaScript-Funktionen vor
Warum Templates nötig sind und wo heute das Problem liegt
- Die DOM-API ist die Grundlage für die dynamischen Fähigkeiten der Webplattform
- Im Standard-DOM gibt es jedoch keine deklarative Möglichkeit, einen DOM-Baum aus Daten sicher zu definieren und effizient zu aktualisieren
- Moderne Web-Frameworks wie React, Vue, Angular und Svelte bieten alle deklaratives Templating
- Gründe für die Beliebtheit deklarativen Templatings:
- Bessere Nutzbarkeit und Lesbarkeit als imperative APIs
- Bessere XSS-Sicherheit durch automatisches Escaping von Daten innerhalb von Templates
- Effiziente und schnelle Rendering-Performance
- Höhere Entwicklerproduktivität durch statische Analyse, Typprüfung und IntelliSense
- Unterstützung für Server-Side Rendering
Probleme der aktuellen Situation
- Nutzer: Langsameres initiales Laden durch Bibliotheks-Downloads und Rendering-Verzögerungen. Größerer Client-Code verschlechtert die UX
- Entwickler: Für die Nutzung von Templates sind zusätzliche Bibliotheken nötig (
npm, CDN usw.). Das erhöht die Einstiegshürde und führt zu nicht standardisierten Abhängigkeiten
- Frameworks: Müssen ihre Templating-Engines selbst implementieren. Dabei bestehen erhebliche Trade-offs zwischen Performance, Funktionsumfang und Codegröße
- Plattform: Ist im Wettbewerb mit nativen Apps im Nachteil. Flutter und SwiftUI bieten beispielsweise eingebaute Templating-Systeme
Warum jetzt der richtige Zeitpunkt ist
- Frühere Versuche rund um Templates (E4X, E4H, HTML-Template-Literale usw.) scheiterten, hatten damals aber vor allem Schwächen bei DOM-Updates
- In Frameworks und der Community haben sich inzwischen genügend Best Practices für Templating-APIs angesammelt
- Ein JavaScript-basiertes API ist heute realistisch. Im standardisierten JS gibt es bereits Tagged Template Literals
- Auch bei Vanilla-JS-Entwicklern und in der Web-Components-Community steigt der Bedarf an komfortabler DOM-Manipulation kontinuierlich
- Parallel dazu laufen zwar Low-Level-Primitive-Vorschläge wie DOM Parts, aber eine deklarative High-Level-API könnte größeren Nutzen stiften und eine klarere Weiterentwicklung vorgeben
Analyse guter Templating-Syntax
- Gängige Templating-Systeme (React-JSX, Vue, Svelte, Angular usw.) basieren letztlich auf sehr ähnlicher Markup-und-Binding-Syntax
- Bei JavaScript-API-basiertem Templating ist es üblich, dass ein Template-Ausdruck eine DOM-Beschreibung zurückgibt und eine separate Render-Funktion diese dann in tatsächliches DOM überführt
- Ältere Ansätze wie E4X gaben direkt DOM zurück und hatten deshalb ein schwächeres Update-Modell
Potenzial einer JavaScript-basierten Templating-API
- Mit Tagged Template Literals lässt sich eine Templating-API entwerfen, ohne neue JavaScript-Funktionen einzuführen
- Dafür gibt es bereits mehrere praktische Nachweise, etwa JSX-to-Lit
Diskussion zur JSX-Integration
- Die Standardisierung von JSX erfordert komplexe Bedeutungsdefinitionen und Runtime-Semantik; JSX selbst ist zunächst nur Syntax
- Das heutige nicht standardisierte JSX ist reine Syntaxtransformation, sodass sich bei Einführung einer standardisierten Templating-API künftig ein Compiler für die Umwandlung von JSX in Template-Literale anschließen ließe
- Falls später eine echte JSX-Standardisierung erfolgt, wäre ein Übergang zu einer an die Templating-API angepassten Datenstruktur gut möglich
Verhältnis zu HTML-basierten Templating-APIs
- Viele Entwickler und Communities wünschen sich ein HTML-basiertes Templating-System
- Ein HTML-basiertes System wäre jedoch deutlich aufwendiger, weil dafür neue Syntax und Ausdrucksformen für Bindings, Ausdruckssprachen und Kontrollstrukturen entworfen werden müssten
- Dass neuere Frameworks wie Lit sich von HTML-Templates hin zu JS-APIs bewegt haben, hat denselben Hintergrund
- Daher sollte zuerst eine JS-basierte Templating-API eingeführt werden; eine schrittweise Erweiterung zu einer HTML-API ist später gut denkbar
Reife aus Erfahrungen mit Reaktivität
- Verschiedene Reaktivitätsmodelle wie VDOM-Diffing (React), Template-Identität (Lit) und Signale (fine-grained signals, Solid/Svelte/Vue usw.) sind inzwischen erprobt
- VDOM-basierte Ansätze sind langsamer, während die Kombination aus Template-Identität und Signalmodell schnell, effizient und gut erklärbar ist
- Signalbasierte Modelle verlangen zwar, dass alle Daten in Signale verpackt werden, können aber auch mit gewöhnlichen Daten kombiniert werden
Entwicklungspfad und erwartete Effekte
- Die vorgeschlagene deklarative JS-Templating-API würde Vanilla JS, Web Components und neuen Frameworks unmittelbare Vorteile bringen
- Sie könnte auch in bestehenden Frameworks als Compile-Target, Runtime-Backend oder direkt unterstützte API genutzt werden
- Unterstützt würden sowohl „Re-Rendering“-Ansätze als auch signalbasierte Reaktivität
- Zugleich entstünde eine Grundlage für spätere Erweiterungen hin zu HTML-basierten deklarativen Templates und deklarativen Custom Elements
- Der API-Umfang wäre eng und klar, und die Anbindung an bestehende APIs (z. B. DOM Parts) wäre ebenfalls einfach
- Auch wenn API-Oberfläche und Syntax einfach wirken, ist der Implementierungsumfang darunter mit DOM Parts, Scheduler usw. groß; Standardisierung, Tests und Zusammenarbeit bleiben nötig
Schluss
- Der Autor diskutiert den Vorschlag in einem GitHub-Issue und bittet die Community, etwa Plattformingenieure, um Beteiligung
1 Kommentare
Hacker-News-Kommentare
Ich muss über die Aussage lachen, man wisse, was eine „gute Template-Syntax“ sei, weil ich nicht glaube, dass es darüber jemals wirklich Einigkeit gegeben hat. Bei Templates ist aus meiner Sicht die visuelle Erfahrung wichtiger als eine symbolische Perspektive. Genau deshalb waren Werkzeuge wie Dreamweaver damals so erfolgreich. Viele Designer beginnen aus demselben Grund mit Tools wie Photoshop zu lernen. Ich finde es schade, dass dieser Versuch so wirkt, als wolle man XSLT noch einmal bauen. Das eigentliche Problem beim Templating ist, schlecht strukturierte Gebilde zu einem gut strukturierten Ergebnis zusammenzuführen. Dazu kommt das Problem, Entitäten auszudrücken, die zwar verbunden sind, wie
labelundfor, aber nicht zum selben Baum gehören. Wenn ich zaubern könnte, würde ich mir wünschen, dass man nicht krampfhaft versucht, alles in ein seltsames Standard-Dokumentlayout zu pressen. Mit geschicktem Einsatz von absoluter Positionierung lassen sich viele UI-Probleme effizient lösen, und ich frage mich, warum man die Maschine immer wieder zwingen will, dabei sämtliche mathematischen Berechnungen zu übernehmenIch stimme zu, dass das wie ein erneuter Versuch wirkt, XSLT zu bauen. XML mochte ich selbst nicht besonders, aber XSLT war wirklich mächtig. Es wird in Browsern immer noch breit unterstützt. XML hatte bei Konfigurationen oder IPC klare Nachteile, aber gerade die Verbindung aus einer starken Markup-Sprache mit der Transformationskraft von XSLT wurde eher nicht richtig genutzt. Dass XSLT nie massentauglich wurde, liegt daran, dass es ein wirklich deklaratives und funktionales DSL ist. Viele reden positiv über DSLs, aber in der Praxis sind sie oft nur eine dünne Hülle um die prozedurale Semantik einer populären Sprache. Mit einem gut entworfenen DSL lassen sich komplexe Dinge einfach erledigen, aber ich glaube, vielen fehlt die Bereitschaft, sich wirklich damit zu beschäftigen
Du sagst, bei einer richtigen Template-Syntax sei Visualität der Kern, und ich würde gern verstehen, wie du zu diesem Schluss kommst. Für mich klingt das eher wie Unzufriedenheit mit HTML+CSS selbst, also mit der Art, wie es erzeugt wird. Ich frage mich auch, warum du absolute Positionierung erwähnst. Sie ist an den richtigen Stellen sicher nützlich, aber für das gesamte Layout macht sie die Pflege eher schwieriger und bricht leicht bei unterschiedlichen Bildschirmgrößen oder Inhaltsmengen auseinander. Selbst Zeitungslayouts enthalten viele subtile Aspekte von Text und Typografie, die sich nicht nur mit absoluter Positionierung lösen lassen. Wenn man tief mit CSS arbeitet, habe ich oft erlebt, dass ein anfangs mit absoluter Positionierung gebautes Layout später durch Flex oder Flow schneller und einfacher zu beheben war. Mit
calc()und Viewport-Einheiten kann man darin einen Sinn sehen, aber in der Praxis ist absolute Positionierung ungeeignet, sobald Inhalte oder Viewport nicht vollständig fixiert sindIch habe schon öfter die Meinung gesehen, dass Leute etwas unnötig kompliziert angehen, das sich mit klug eingesetzter absoluter Positionierung leicht und schnell umsetzen ließe, nur um am Ende denselben Effekt zu erzielen. Im Web gibt es aber die Anforderung, dass ein Dokument auf Geräten aller Größen, Ausrichtungen und Leistungsstufen gut aussehen muss. Normale Apps, etwa Windows-Apps, haben dieses Problem nicht, und bei mobilen Apps muss man oft nur standardisierte Bildschirmgrößen berücksichtigen. Nur das Web muss all das gleichzeitig abdecken
Auf die Formulierung „gute Template-Syntax“ spöttisch zu reagieren, ist meiner Meinung nach keine besonders höfliche Haltung gegenüber jemandem, der Fortschritt erreichen will. Und ich denke schon, dass es heute gute Template-Syntax gibt, nämlich beispielhaft jsx. Ich bin kein Fan von React, aber ich glaube, dass jsx die Webentwicklung revolutioniert hat und dass die meisten js-Template-Systeme heute fast alle bei „Template als Ausdruck“, „Komposition durch Verschachtelung“ und einer Behandlung des Kontrollflusses in JavaScript angekommen sind
React und Svelte sehen sich nur oberflächlich ähnlich, tatsächlich funktionieren sie ziemlich unterschiedlich. Bei React ist entscheidend, dass (fast) normale JavaScript-Funktionen lazy Markup in Form von JSX zurückgeben. Es gibt keine eigene Template-Syntax für Schleifen oder bedingtes Rendering; alles wird mit normalem JavaScript erledigt, und das ist der wesentliche Unterschied
Ich lerne immer wieder, dass API und ABI (Application Binary Interface) niemals wirklich endgültig sind. Anforderungen an Apps sind nicht statisch, sondern verändern sich im Lauf der Zeit ständig, deshalb gibt es keine perfekte API, die für immer ausreicht. Dieser Vorschlag ist ein gutes Beispiel dafür. Zuerst lösen Userland-Bibliotheken wie React ein Problem, und irgendwann wandert es als Standard nach unten. Bei Polyfills sieht man dasselbe Muster. Selbst wenn ein solcher Vorschlag erfolgreich ist, wird er am Ende zu Alttechnik, und die Leute finden neue Wege, ihn zu umgehen. DOM-APIs, ECMA, alte Browser — ihnen allen droht dasselbe Schicksal. Das bringt mich zu der Frage, ob man technische Entropie, Erweiterbarkeit und Abwärtskompatibilität selbst als Standard-Anwendungsfälle betrachten sollte
Neue Funktionen in Webstandards bedeuten am Ende immer eine enorme Wartungslast im Code, und Browser, die Standards einhalten wollen, müssen ständig mehr implementieren. Projekte wie Servo sind dadurch in einer Lage, in der sie kaum aufholen können und immer nur Erweiterungen hinterherlaufen. Ich wünsche mir, dass die Webplattform alle Funktionen nativer Umgebungen bekommen kann, innerhalb der Grenzen von Datenschutz und Sandbox. Ich will auch eine hervorragende Developer Experience. Aber um diesen Traum zu verwirklichen, muss man den Preis steigender Komplexität mitbedenken. Ich bin nicht überzeugt, dass das hier diskutierte native Templating die Developer Experience wirklich deutlich verbessert
Wenn man Abwärtskompatibilität wahrt und Schnittstellen nicht verändert, ist das dann nicht genau die Aufgabe von Versionierung?
Die Behauptung ist, dass man alte Dinge irgendwann immer umgeht oder flickt, aber dieser Prozess hat auch den positiven Effekt, dass die zugrunde liegenden Fähigkeiten auf eine neue Stufe gehoben werden. Inkrementelle Updates sind absolut wertvoll, selbst wenn Nutzeranforderungen ständig neue Lücken und Anwendungsfälle sichtbar machen
Der Aussage „API und ABI sind nie dauerhaft stabil“ stimme ich nicht zu.
getElementByIdist zum Beispiel seit über 25 Jahren stabil. Zu sagen, unveränderliche APIs seien unmöglich, wirkt eher wie persönliche Resignation, und es gibt zahllose Gegenbeispiele. Die Nachfrage hört nie auf, also fügt man eben neue APIs hinzu. Es gibt keinen Grund, funktionierende APIs kaputtzumachenIm Web wird es bei jeder einmal veröffentlichten API Nutzer geben, die genau von ihrer konkreten Form ein Leben lang abhängen. Deshalb hallen Entscheidungen von vor 20 Jahren oft bis heute nach. Man sieht das etwa an Fällen wie „smooshgate“
Unter Verweis auf den Hype um reaktive Programmierung wird gesagt, dass das Userland diesen Bereich inzwischen ausreichend erprobt habe und man nun die Vorteile der verschiedenen Ansätze zu einem echten Standardsystem zusammenführen könne. Ich denke aber, dass Leute wie Ryan Carniato bzw. Solid JS mit Signals immer noch neue Möglichkeiten erkunden, also ist diese Erkundungsphase noch nicht vorbei. Es gibt noch reichlich Raum für Weiterentwicklung
Das Web braucht wirklich natives Templating, Reaktivität und Data Binding. Die Verschwendung an CPU und Bandbreite ist kaum vorstellbar, wenn Milliarden Nutzer weltweit schwere Frameworks wie React herunterladen, parsen und ausführen
Verglichen mit der gewaltigen Ressourcenverschwendung durch LLMs und Kryptografie wirkt diese Verschwendung fast vernachlässigbar
Bei TC39 gibt es einen Signals-Vorschlag, und dadurch geht es einen Schritt weiter
Für die tatsächliche Entwicklung braucht man im Grunde nur bidirektionales Data Binding und so etwas wie einen jsx-Klon
React ist kein Template-System
Wenn ich die Diskussion über ein hochrangiges Template-System in Webstandards verfolge, denke ich eher, dass zuerst niedrigstufige, browserinterne APIs bereitgestellt werden sollten. Dass sich alle auf ein Standard-Template-System einigen, ist beinahe unmöglich. Stattdessen sollte der Browser eine Low-Level-API bereitstellen, die Diffs auf das DOM anwenden kann. Es wäre zum Beispiel schön, wenn es nativ eine Methode wie diese gäbe:
element.applyDiff(DocumentFragment | string, { method: 'innerHTML' | 'outerHTML' }). Mit einem solchen Diff könnte man das aktuelleelementzerstörungsfrei aktualisieren und dabei Fokus, Input-Werte sowie Audio-/Video-Zustände erhalten. Es gibt JavaScript-Bibliotheken wie Idiomorph, aber eine native Lösung wäre vermutlich deutlich schnellerDer Autor dieses Textes wird als jemand mit Erfahrung auf höchstem Niveau in diesem Bereich vorgestellt. Er hat maßgeblich zu Lit, Polymer, Googles Web Components und mehreren zentralen DOM-Spezifikationen beigetragen
Statt des JSX-Ansatzes hätte ich gern eine syntaktische Richtung wie bei Kotlin, das DSLs mit Receivern und Buildern verallgemeinert. So etwas wäre nicht nur für einfache HTML-Templates nützlich, sondern auch für verschiedenste Komponenten-Hierarchien, Konfigurationen und andere Kontexte. Was Templating und Data Binding in Wirklichkeit bedeuten, ist letztlich nur eine standardisierte Menge von Funktionen, die solche Sprachmerkmale ausnutzen — ähnlich wie Jetpack Compose
Ich bin mir nie ganz sicher gewesen, ob deklaratives Templating wirklich besser ist als jQuery. Ich nutze React seit fast zehn Jahren, aber je komplexer mein SPA wird, desto mehr vermisse ich imperative Kontrolle über das DOM. Die DOM-Abstraktion leckt, und am Ende sind einfache Muster wie „last-write-wins“ oft klarer. Deklarative Templates sollen solche Probleme lösen, aber sobald Komponenten mutable Zustände gemeinsam nutzen, zeigen sich die Grenzen sehr schnell
Dieses Gefühl entsteht zum Teil auch dadurch, dass React-Entwickler direkte DOM-API-Aufrufe fast als Sünde behandeln. Es ist aber völlig in Ordnung,
refaktiv zu verwenden oder Komponenten direkt peridzu finden und zu manipulieren. Tatsächlich arbeiten schnelle Formularbibliotheken mit wenigen Re-Renders oft genau soIch mag React nicht besonders, aber ich finde nicht, dass es eine echte Hürde gibt, in einer deklarativen DOM-Welt auf
innerHTML,refund Ähnliches zurückzugreifen. Imperative Kontrolle ist möglich, aber praktisch gibt es nicht viele Dinge, die man deklarativ gar nicht umsetzen kann. SelbstattachShadow()odershowModal()lassen sich mit vielleicht zehn zusätzlichen Zeilen leicht deklarativ kapselnWenn der Records-and-Tuples-Proposal Fortschritte gemacht hätte, hätte JSX diese Strukturen für neue Semantik nutzen können, aber tatsächlich wurde der Proposal nicht nur gestoppt, sondern komplett zurückgezogen (siehe Issue). Er wurde stattdessen durch den Composites-Proposal ersetzt
Ich finde, diese Diskussionen über die Standardisierung solcher High-Level-Funktionen sollten aufhören. Stattdessen sollte man Low-Level-Eigenschaften erweitern und sich auf Richtungen konzentrieren, die für die Implementierung darüberliegender Bibliotheken mehr Wert bieten. Ein Standardvorschlag ist nur sinnvoll, wenn er gegenüber Bibliotheken klare Vorteile hat. Über Standardisierung sollte man meiner Meinung nach erst dann sprechen, wenn etwas als Bibliothek mindestens 5 bis 10 Jahre breit erprobt worden ist