- Mit der Veröffentlichung von Dagger Cloud v3 wurde die neue UI in WebAssembly (WASM) und Go geschrieben
- Go wird normalerweise nicht für die Entwicklung von Web-UIs verwendet, aber dieser Ansatz wurde gewählt, um die „Codebase zu vereinheitlichen und die Performance zu optimieren“
- Dieser Artikel teilt den „Hintergrund der Entscheidung, die Herausforderungen bei der Implementierung und das Endergebnis“
Das bisherige Problem: Ineffizienz durch zwei Codebases
- Dagger arbeitet auf Basis eines DAG (Directed Acyclic Graph) und visualisiert diesen sowohl in der TUI (Terminal UI) als auch im Web-Dashboard (Dagger Cloud)
- Bisher war die TUI in Go und die Web-UI in React/TypeScript umgesetzt
- Die Synchronisierung zwischen den beiden UIs war jedoch schwierig, und besonders in der Web-UI traten Performance-Probleme bei der Echtzeitverarbeitung großer Datenmengen auf
- Beim Verarbeiten komplexer OpenTelemetry-Event-Streams mit Hunderttausenden von Spans wurden Performance-Einbrüche und Geschwindigkeitsprobleme der React-UI besonders deutlich
- Dieselben Funktionen mussten zweimal implementiert werden, was für ein kleines Team eine große Entwicklungslast bedeutete
- Deshalb wurde ein neuer Ansatz mit dem Ziel geprüft, die Codebase zu vereinheitlichen und die Performance zu optimieren
Die gewählte Lösung: Go + WebAssembly
- Vereinheitlichung der Codebase mit Go
- Da die TUI bereits in Go implementiert war, konnte durch eine Web-UI in Go Code wiederverwendet werden
- Im Team gibt es viele Go-Entwickler, was die Produktivität erhöht und die Wartung vereinfacht
- Einsatz von WebAssembly (WASM)
- WebAssembly wurde eingeführt, damit Go-Code direkt im Browser ausgeführt werden kann
- Allerdings ist das Ökosystem rund um Go + WASM noch nicht ausgereift, wodurch einige Herausforderungen entstehen:
- Mangel an Komponentenbibliotheken → Die UI musste direkt selbst implementiert werden
- WASM-Speicherlimit im Browser (2 GB) → Bei großen Datenmengen ist Optimierung nötig
- Diese Speicheroptimierung kann jedoch sowohl der TUI als auch der Web-UI zugutekommen
Strategie zur Minimierung des Projektrisikos
- Verwendung des Go-app-Frameworks
- Gewählt wurde ein Go-basiertes Framework für die Entwicklung von PWAs (Progressive Web Apps)
- Es bietet ein komponentenbasiertes Modell ähnlich wie React, wodurch der Umstieg leichter fiel
- Prototyping und Validierung
- Die bestehende UI wurde so weit wie möglich in Go-app nachgebaut, um zentrale Probleme früh zu identifizieren
- WASM ist bereits als offener Standard dokumentiert, und die wichtigsten Fragen ließen sich in der Go-app-Dokumentation klären
- Das größte Problem war das Speicherlimit, weshalb dafür Design- und Optimierungsarbeit nötig war
Vom Prototyp zur Produktion
Strategien zur Performance-Optimierung
- Optimierung des Renderings großer Logmengen
- Bei der Verarbeitung von mehr als 200.000 Logzeilen musste die Rendering-Performance verbessert werden
- Dafür wurde die virtuelle Terminal-Rendering-Bibliothek
midterm optimiert,
→ was die Performance sowohl der TUI als auch der Web-UI verbesserte
- Verbesserung der JSON-Parsing-Geschwindigkeit
- Go WASM ist beim JSON-Parsing langsam → deshalb wurde ein intelligentes Backend auf WebSocket-Basis entworfen
- Die Datenübertragung wurde mit Go
encoding/gob optimiert
- Optimierung der WASM-Dateigröße
- Ursprüngliche Größe der WASM-Datei: 32 MB
- Nach Anwendung von Brotli-Kompression: 4,6 MB
- Da sich die Kompression im CDN nur schwer umsetzen ließ, wurde sie direkt in den Build-Prozess integriert
Weitere Verbesserungen
- Abgesehen vom erwarteten Speicherproblem erwiesen sich die meisten Sorgen als unbegründet
- Das Schreiben von UI-Komponenten war nicht schwierig, und auch die Integration mit anderen Diensten (Tailwind, Auth0 usw.) verlief problemlos
- Die Nutzung von NPM-Paketen in WebAssembly ist möglich → Interoperabilität mit JavaScript ist gewährleistet
- Go-app bietet bei der Aktualisierung von Komponenten mehr Flexibilität als React, was mehr Spielraum für Optimierungen schafft
- Performance-Analysen sind mit Go-Profiling-Tools (
pprof) und dem integrierten Browser-Profiler möglich
- Dank PWA-Unterstützung kann die Anwendung als Desktop-/Mobile-App ausgeführt werden, ohne dass der Browser geöffnet sein muss
Vorteile nach der Umstellung
- Bessere UI-Konsistenz
- Da TUI und Web-UI dieselbe Codebase verwenden, bieten sie eine konsistentere UX
- Verbesserte Performance und geringerer Speicherverbrauch
- Beim Umgang mit großen Datenmengen verbesserten sich Rendering-Geschwindigkeit und Speicherverbrauch
- Höhere Team-Produktivität
- Früher mussten Web-UI und TUI jeweils separat optimiert werden,
jetzt lassen sich beide Interfaces mit einer einzigen Optimierung gleichzeitig verbessern
- Dadurch kann sich das Team stärker auf die Entwicklung neuer Funktionen konzentrieren
Sollte man auf Go + WASM umsteigen?
- Im Allgemeinen nicht zu empfehlen, aber unter bestimmten Bedingungen kann es sinnvoll sein:
- Teams mit vielen Go-Entwicklern
- Komplexe UIs, bei denen TypeScript/React an Performance-Grenzen stößt
- Bedarf an Code-Sharing zwischen TUI und Web-UI
- Umgebungen, in denen Entwicklungsgeschwindigkeit maximal wichtig ist
- Wenn diese Bedingungen erfüllt sind, kann Go + WASM eine gute Alternative sein
In den meisten Fällen sind jedoch bestehende Web-Technologien (React, TypeScript usw.) besser geeignet
6 Kommentare
Ist das so etwas wie das frühere GWT?
Hm … ob die Entwicklung damit wirklich typsicherer wird als mit TS, das würde mich schon interessieren.
Irgendwie wirkt es so, als würde hier ein einfaches Problem unnötig kompliziert gelöst ...
Die Entwicklung von Frontends auf Go-Basis ist effektiver als erwartet. Es gibt gute Gründe dafür, dass die Zahl der Use Cases zunimmt.
Trotzdem würde ich es gern mal ausprobieren.
Hacker-News-Kommentare
Es gibt die Ansicht, dass man als kleines Team schnell ausliefern muss
Es gab ein starkes Go-Engineering-Team und eine komplexe UI, die sich mit TypeScript/React nur schwer skalieren ließ
Es habe die Sorge gegeben, ob es ein Framework sei, das „auf Canvas rendert“, aber das sei nicht der Fall
Sie hätten sich entschieden, das Frontend mit <a href="https://go-app.dev/" rel="nofollow">https://go-app.dev/</a> zu bauen
Es gibt die Meinung, dass Go für diese Art von Arbeit nicht geeignet ist
Ein späterer Follow-up-Bericht in ein paar Monaten darüber, ob der Wechsel von einem schwereren Stack zu einem performanteren, aber etwas ungewöhnlichen Stack positive Ergebnisse bringt, wäre interessant
Der Gründer von go-app habe diesen Beitrag entdeckt und sei überrascht gewesen; er wünsche dem Produkt viel Erfolg
Weil Go WASM beim Parsen von JSON langsam ist, habe man die Architektur geändert und ein „smartes Backend“ für inkrementelles Datenladen über WebSockets gebaut
Es gibt die Meinung, dass WASM für bestimmte Nischenanwendungen geeignet ist, aber ungeeignet für den Bau allgemeiner Web-Apps
Man halte es für sehr wertvoll, alle Komponenten (Frontend/Backend/App) in derselben Sprache zu nutzen