- Avec le lancement de Dagger Cloud v3, la nouvelle UI a été développée en WebAssembly (WASM) et en Go
- Go n’est généralement pas utilisé pour le développement d’UI web, mais cette approche a été choisie pour « unifier la base de code et optimiser les performances »
- Cet article partage « le contexte de ce choix, les défis rencontrés lors de l’implémentation et le résultat final »
Problème initial : l’inefficacité liée à deux bases de code
- Dagger fonctionne sur la base d’un DAG (Directed Acyclic Graph), qu’il visualise dans la TUI (interface terminal) et le dashboard web (Dagger Cloud)
- Auparavant, la TUI était implémentée en Go et l’UI web en React/TypeScript
- Mais il était difficile de maintenir la synchronisation entre les deux UI, et l’UI web rencontrait notamment des problèmes de performances pour traiter de gros volumes de données en temps réel
- Lors du traitement de flux complexes d’événements OpenTelemetry, avec des centaines de milliers de spans, la dégradation des performances et les problèmes de vitesse de l’UI React sont devenus particulièrement visibles
- Il fallait implémenter les mêmes fonctionnalités deux fois, ce qui représentait une lourde charge de développement pour une petite équipe
- D’où la recherche d’une nouvelle approche visant à unifier la base de code et à optimiser les performances
Solution retenue : Go + WebAssembly
- Unification de la base de code avec Go
- La TUI étant déjà implémentée en Go, développer aussi l’UI web en Go permettait de réutiliser le code
- L’équipe comptant de nombreux développeurs Go, cela améliore la productivité et facilite la maintenance
- Utilisation de WebAssembly (WASM)
- WebAssembly a été adopté pour permettre l’exécution directe du code Go dans le navigateur
- Cependant, l’écosystème Go + WASM n’est pas encore mature, ce qui pose plusieurs défis :
- Manque de bibliothèques de composants → il a fallu implémenter l’UI directement
- Limite mémoire WASM du navigateur (2 Go) → nécessité d’optimiser pour traiter de gros volumes de données
- En contrepartie, ces optimisations mémoire peuvent profiter à la fois à la TUI et à l’UI web
Stratégie pour minimiser les risques du projet
- Utilisation du framework Go-app
- Choix d’un framework basé sur Go pour développer une PWA (Progressive Web App)
- Il propose un modèle à composants proche de React, ce qui facilite la transition
- Création et validation d’un prototype
- Réimplémentation autant que possible de l’UI existante avec Go-app afin d’identifier les principaux problèmes
- WASM étant déjà un standard ouvert bien documenté, les principales questions ont pu être résolues via la documentation de Go-app
- Le principal enjeu restait la limite d’utilisation mémoire, qui demandait une conception et des optimisations spécifiques
Du prototype à la production
Stratégies d’optimisation des performances
- Optimisation du rendu de grands volumes de logs
- Il fallait améliorer les performances de rendu lors du traitement de plus de 200�0 lignes de logs
- Pour cela, la bibliothèque de rendu de terminal virtuel
midterm a été optimisée,
→ avec un gain de performances à la fois pour la TUI et l’UI web
- Accélération du parsing JSON
- Le parsing JSON est lent avec Go WASM → conception d’un backend intelligent basé sur WebSocket
- Utilisation de
encoding/gob de Go pour optimiser le transfert des données
- Optimisation de la taille du fichier WASM
- Taille initiale du fichier WASM : 32 Mo
- Application de la compression Brotli → réduction à 4,6 Mo
- Comme le CDN gérait difficilement cette compression, elle a été appliquée directement dans le processus de build
Autres améliorations
- En dehors des problèmes mémoire anticipés, la plupart des inquiétudes se sont révélées infondées
- L’écriture des composants UI n’a pas été particulièrement difficile, et l’intégration avec d’autres services (Tailwind, Auth0, etc.) n’a posé aucun problème
- Il est possible d’utiliser des packages NPM depuis WebAssembly, ce qui garantit l’interopérabilité avec JavaScript
- Go-app offre une gestion des mises à jour de composants plus souple que React, avec davantage de liberté pour l’optimisation
- Les outils de profilage Go (
pprof) ainsi que le profiler intégré au navigateur permettent d’analyser les performances
- Grâce au support PWA, l’application peut s’exécuter comme une app desktop ou mobile, sans avoir à ouvrir le navigateur
Bénéfices obtenus après la migration
- Amélioration de la cohérence de l’UI
- La TUI et l’UI web utilisent la même base de code, ce qui offre une UX plus cohérente
- Amélioration des performances et de l’utilisation mémoire
- Lors du traitement de gros volumes de données, la vitesse de rendu s’améliore et l’utilisation mémoire diminue
- Hausse de la productivité de l’équipe
- Auparavant, il fallait optimiser séparément l’UI web et la TUI ;
désormais, une seule optimisation peut être appliquée simultanément aux deux interfaces
- Cela permet de se concentrer davantage sur le développement de nouvelles fonctionnalités
Faut-il migrer vers Go + WASM ?
- En règle générale, ce n’est pas recommandé, mais cela peut être utile dans certains cas :
- équipe avec de nombreux développeurs Go
- UI complexe où TypeScript/React atteint ses limites de performance
- besoin de partager du code entre TUI et UI web
- environnement où il faut maximiser la vitesse de développement
- Si ces conditions sont réunies, Go + WASM peut être une bonne alternative
Mais dans la plupart des cas, les technologies web existantes (React, TypeScript, etc.) restent plus adaptées
6 commentaires
C’est comme l’ancien GWT ?
Hum… je me demande si cela permettra vraiment un développement plus sûr au niveau des types que TS.
J’ai beau regarder, j’ai l’impression qu’ils compliquent un problème simple...
La création de frontends basés sur Go est plus efficace qu’on ne le pense. S’il y a de plus en plus de cas d’usage, ce n’est pas sans raison.
J’aimerais bien essayer quand même.
Avis Hacker News
Certains estiment qu’en tant que petite équipe, ils devaient livrer rapidement
Ils disposaient d’une solide équipe d’ingénieurs Go et d’une UI complexe difficile à faire évoluer avec TypeScript/React
Certains craignaient qu’il s’agisse d’un framework qui « rend sur canvas », mais ce n’est pas le cas
Ils ont décidé de créer le frontend avec <a href="https://go-app.dev/" rel="nofollow">https://go-app.dev/</a>
Certains jugent que Go n’est pas adapté à ce type de travail
Un retour quelques mois plus tard serait intéressant pour voir si le passage d’une stack plus lourde à une stack plus performante mais un peu atypique donne des résultats positifs
Le créateur de go-app est tombé sur ce billet, s’en est dit surpris et a souhaité la réussite du produit
La lenteur de Go WASM pour parser le JSON les a poussés à modifier l’architecture et à créer un « backend intelligent » pour charger progressivement les données via WebSockets
Certains estiment que WASM convient à des usages de niche bien précis, mais pas à la création d’apps web généralistes
Certains voient une grande valeur dans l’usage d’un langage unique pour tous les composants (frontend/backend/app)