Ein auf dem JetBrains Blog veröffentlichter Artikel untersucht die Möglichkeit, Compose HTML zum Erstellen serverseitig gerenderter Weboberflächen in einer Kotlin-Umgebung zu verwenden – zu einem Zeitpunkt, an dem mehrere Frameworks einen Teil der Verarbeitung von Benutzeroberflächen wieder auf den Server verlagern. Der vorgeschlagene Ansatz besteht darin, wiederverwendbare und typsichere Compose-Komponenten bereitzustellen, anstatt von Anwendungscode getrennte Textvorlagen zu schreiben. Der Artikel betont, dass es sich bei den vorgestellten Inhalten um eine Erkundung von Ideen und nicht um eine offizielle Verpflichtung von JetBrains oder eine Ankündigung von APIs oder einer Roadmap handelt.
Der Ansatz geht von einem Vergleich mit Entwicklungen in anderen Ökosystemen aus: React führte Server Components ein, HTMX weckte das Interesse am Hypermedia-Modell erneut, und Phoenix LiveView zeigte, dass interaktive Aktualisierungen vom Server aus möglich sind, ohne auf ein Client-Framework angewiesen zu sein. Der Artikel vertritt die Ansicht, dass das JVM-Ökosystem zahlreiche Bibliotheken für serverseitiges Rendering besitzt, diese jedoch häufig Template-Sprachen verwenden und keine Komponenten bieten, die dem von JavaScript-Entwicklern bekannten Komponentenmodell ausreichend nahekommen.
Warum Compose HTML?
Compose Multiplatform bietet eine Möglichkeit, Geschäftslogik und Benutzeroberflächen einmal zu schreiben und sie zwischen Android, iOS, Desktopgeräten und dem Web zu teilen. Die derzeitige Web-Zielplattform von Compose Multiplatform basiert jedoch auf der direkten Darstellung innerhalb eines Canvas, was laut Artikel mit Kosten in Bezug auf Suchmaschinenoptimierung, Ladezeiten und Barrierefreiheit verbunden ist.
Compose HTML, das älter ist als Compose for Web, verwendet die Compose Runtime, um Single-Page-Anwendungen in Kotlin zu erstellen und sie anschließend über den Kotlin/JS-Compiler in JavaScript zu übersetzen. Der Artikel schlägt vor, dafür ein JVM-Ziel hinzuzufügen, damit serverseitiges Rendering möglich wird. Dabei würde der HTML-Baum direkt in Kotlin mithilfe echter Komponenten und Typen erstellt – ohne separate Template-Sprache.
Die Quelle zeigt ein Gegenüberstellung zwischen einer in Thymeleaf geschriebenen Kartenkomponente und einer Compose-Komponente. Im templatebasierten Modell wird die Karte in einer separaten Datei definiert, und Parameter werden als nicht typgeprüfte Zeichenketten übergeben. In Compose ist die Karte dagegen eine typisierte Funktion, die einen Titel vom Typ String und eine Zahl vom Typ Int entgegennimmt. Wird der Name eines Parameters geändert, werden daher entweder die Verwendungsstellen über die Entwicklungsumgebung aktualisiert oder es tritt ein Fehler während der Kompilierung auf. Ebenso führt die Übergabe eines falschen Typs zu einem Compilerfehler statt zu einer Überraschung zur Laufzeit.
Vorstellung des serverseitigen Renderings
Der vorgeschlagene Ansatz erfordert das Hinzufügen von Funktionen wie renderToString und renderToBytes, um die Composition einmalig auf der JVM auszuführen und den resultierenden Baum anschließend in HTML-Text oder Byte-Daten umzuwandeln. Dem angeführten Beispiel zufolge erstellt der Vorgang Komponenten wie Text und Containerelemente, wartet auf die Stabilisierung der initialen Composition, durchläuft anschließend den resultierenden Baum und wandelt ihn ohne Browser oder DOM in HTML um.
Dieses Modell weist klare Einschränkungen auf. Wahrscheinlich würde es sich auf eine einzige Rendering-Phase beschränken, ohne erneute Composition bei Zustandsänderungen oder die Ausführung von Effekten. Damit wäre es dem Konzept des serverseitigen Renderings in JavaScript-Frameworks ähnlich. Ereignis-Listener könnten in den Komponenten zwar akzeptiert werden, wären auf dem Server jedoch inaktiv, da es keinen Nutzen hätte, während der HTML-Erstellung dort Browserereignisse zu verknüpfen.
Der Artikel stellt die Vorstellung einer vollständigen Aufgabenanwendung mit Spring Boot vor. Dabei würde eine GET-Route die Aufgabenseite rendern, während POST-Anfragen eine neue Aufgabe hinzufügen oder deren Status ändern. Die Interaktionen würden in diesem Szenario auf dem Absenden echter HTTP-Formulare und dem erneuten Laden der Seite beruhen – ohne JavaScript auf der Clientseite. Dies wäre vergleichbar mit herkömmlichen Rendering-Anwendungen mit Thymeleaf, wobei die gesamte Benutzeroberfläche innerhalb von Compose geschrieben wird.
Die aktuelle Landschaft und mögliche Frameworks
Compose HTML besitzt derzeit ausschließlich ein JS-Ziel und bietet daher kein serverseitiges Rendering. Der Artikel weist jedoch auf ein aktives Ökosystem rund um Compose für das Web hin. Das Framework Kobweb basiert auf Compose HTML und unterstützt den Export statischer Websites sowie Pre-Rendering zur Verbesserung der Sichtbarkeit in Suchmaschinen, bietet jedoch kein SSR. Kilua verwendet dagegen direkt die Compose Runtime zur Umsetzung von SSR und CSR und bietet Integrationen mit Ktor, Spring Boot und anderen Systemen, während Summon Unterstützung für SSR und Hydration bereitstellt.
Der Ansatz vertritt die Ansicht, dass das Hinzufügen von SSR-Funktionen zu Compose HTML Kobweb, Kilua und Summon eine gemeinsame Grundlage statt drei getrennter Wege geben könnte. Außerdem könnten Spring Boot und Ktor dadurch einen praktischen Grund erhalten, Compose HTML auf dem Server zu integrieren. Dieses Ergebnis ist jedoch weder garantiert noch angekündigt; der Artikel beschreibt es als eine mögliche Richtung, die Experimente und eine Festlegung der erforderlichen Integrationspunkte erfordert.
Über das initiale Rendering hinaus
Die Erkundung führt anschließend zur Frage nach Hydration und Zustandssynchronisierung: Wie setzen auf dem Server gerenderte Komponenten ihre interaktive Arbeit im Browser fort? Und müssen sich Server und Client auf einen gemeinsamen Zustand einigen? Der Artikel weist darauf hin, dass die Lösung dieser Fragen das Teilen von UI-Code zwischen beiden Seiten ermöglichen könnte. Dabei würde dieselbe Komponente für den Browser und den Server übersetzt und vollständig in Kotlin geschriebene, umfassend interaktive Webanwendungen würden unterstützt.
Der Ansatz schlägt jedoch nicht vor, Compose HTML in ein fertiges, vollständiges Framework umzuwandeln, das alle Komponenten und Funktionen umfasst. Das nächstliegende Ziel besteht laut Quelle darin, den Kern klein zu halten und den Aufbau von Framework-Integrationen und Ökosystembibliotheken der Community zu überlassen – ähnlich dem Ansatz von React, jedoch innerhalb einer Multiplattformbibliothek. Dies unterscheidet sich von anderen Teilen von Compose Multiplatform, die offizielle Bibliotheken für Material3, Zustandsverwaltung und weitere Bereiche bereitstellen.
Laut Artikel finden Gespräche mit den Entwicklern von Kobweb, Kilua und Summon statt, um deren Meinungen einzuholen. Auch das Spring-Team zeigte Interesse an einem Experiment, nachdem ein JVM-Ziel zu Compose HTML hinzugefügt worden war. Der aktuelle Wert dieses Ansatzes liegt daher in der Bestimmung einer möglichen Richtung für die Webentwicklung auf der JVM, nicht in der Bereitstellung eines verfügbaren Produkts oder einer bestätigten Funktion. Sollte sich die Idee weiterentwickeln, wird die zentrale Herausforderung darin bestehen, ein Gleichgewicht zwischen einem einfachen Kern, der Integration in Server-Frameworks sowie den Anforderungen an Interaktivität und die Wiederverwendung von Komponenten zwischen Client und Server zu finden.