- Dagger Cloud v3のリリースにあたり、新しいUIはWebAssembly(WASM)とGoで記述
- Goは一般的にWeb UI開発には使われないが、「コードベースの統合とパフォーマンス最適化」のためにこの方式を選択
- この記事では「選択の背景、実装過程での課題、そして最終的な結果」を共有
既存の問題: 2つのコードベースによる非効率
- DaggerはDAG(Directed Acyclic Graph)ベースで動作し、これをTUI(ターミナルUI) と Webダッシュボード(Dagger Cloud) で可視化して提供
- 従来はTUIはGo、Web UIはReact/TypeScriptで実装されていた
- しかし2つのUI間の同期が難しく、特にWeb UIでは大量のデータをリアルタイム処理する際に性能上の問題が発生
- 複雑なOpenTelemetryイベントストリーム(数十万件のスパン)を処理する中で、React UIのパフォーマンス低下と速度の問題が目立っていた
- 同じ機能を2回実装する必要があり、これは小規模チームにとって大きな開発負担だった
- そのため、コードベースの統合とパフォーマンス最適化を目標に新しいアプローチを検討
選択した解決策: Go + WebAssembly
- Goでコードベースを統合
- TUIはすでにGoで実装されており、Web UIもGoで実装すればコード再利用が可能
- チーム内にGo開発者が多く、チームの生産性向上と保守のしやすさにつながる
- WebAssembly(WASM)の活用
- Goコードをブラウザ上で直接実行できるようにするためWebAssemblyを導入
- ただしGo + WASMはまだ成熟したエコシステムを持たず、いくつかの課題が存在:
- コンポーネントライブラリが不足 → UIを自前で実装する必要がある
- ブラウザのWASMメモリ制限 (2GB) → 大量データを扱う際に最適化が必要
- ただし、メモリ最適化はTUIとWeb UIの両方に利点をもたらしうる
プロジェクトリスクを最小化する戦略
- Go-appフレームワークの使用
- PWA(Progressive Web App)開発のためのGoベースのフレームワークを選択
- Reactに似たコンポーネントベースのモデルを提供し、移行しやすい
- プロトタイプの作成と検証
- 既存UIをできるだけGo-appで再実装し、主要な課題を把握
- WASMはすでにオープン標準として文書化されており、主要な疑問はGo-appのドキュメントで解決可能
- 最大の問題はメモリ使用量の制限であり、これを解決するための設計と最適化が必要
プロトタイプから本番移行までの過程
パフォーマンス最適化戦略
- 大規模ログレンダリングの最適化
- 20万行を超えるログデータを処理する際、レンダリング性能の改善が必要
- そのため仮想ターミナルレンダリングライブラリ(midterm)を最適化し、
→ TUIとWeb UIの両方で性能が向上
- JSONパース速度の改善
- Go WASMはJSONパースが遅い → WebSocketベースのスマートなバックエンドを設計
- Goの
encoding/gob を使ってデータ転送を最適化
- WASMファイルサイズの最適化
- 初期のWASMファイルサイズ: 32MB
- Brotli圧縮を適用 → 4.6MBまで削減
- CDNでは圧縮処理が難しかったため、ビルドプロセスで直接圧縮を適用
その他の改善点
- 想定していたメモリ問題以外は、ほとんどの懸念が杞憂だった
- UIコンポーネントの作成は難しくなく、他サービス(Tailwind, Auth0など)との統合にも問題はなかった
- WebAssemblyでNPMパッケージの活用が可能 → JavaScriptとの相互運用性を確保
- Go-appはReactよりコンポーネント更新方式が柔軟で、最適化の自由度が高い
- Goのプロファイリングツール(pprof)やブラウザ内蔵プロファイラで性能分析が可能
- PWA対応により、デスクトップ/モバイルアプリとして実行可能で、ブラウザを開かずにアプリを実行できる
移行後に得られた利点
- UIの一貫性向上
- TUIとWeb UIが同じコードベースを使うことで、より一貫したUXを提供
- パフォーマンスとメモリ使用量の改善
- 大量データを扱う際にレンダリング速度が向上し、メモリ使用量も減少
- チーム生産性の向上
- 以前はWeb UIとTUIをそれぞれ最適化する必要があったが、
今では1回の最適化を2つのインターフェースに同時適用可能
- その結果、新機能開発により集中できるようになった
Go + WASMへ移行すべきか?
- 一般的には推奨しないが、特定の条件では有用な場合がある:
- Go開発者が多いチーム
- TypeScript/Reactが性能限界を見せる複雑なUI
- TUIとWeb UIの間でコード共有が必要
- 開発速度を最大化する必要がある環境
- 上記条件に当てはまるなら、Go + WASMは有力な代替案になりうる
ただし、ほとんどの場合は既存のWeb技術(React, TypeScriptなど)の方が適している
6件のコメント
昔のGWTみたいなものですか?
うーん…TSより型安全な開発になるのか、それは気になりますね
どう見ても、簡単な問題をわざわざ難しく解いているようにしか見えない……
思った以上に、Goベースのフロントエンド開発は効果的です。ユースケースが増えているのには理由があるのだと感じました。
それでもやってみたくはありますね。
Hacker Newsの意見
小規模なチームとして、迅速にデプロイする必要があったという意見がある
強力なGoエンジニアチームがあり、TypeScript/Reactでは拡張しにくい複雑なUIがあった
「Canvasにレンダリング」するフレームワークなのではと心配したが、そうではなかった
彼らは <a href="https://go-app.dev/" rel="nofollow">https://go-app.dev/</a> を使ってフロントエンドを構築することに決めた
Goはこの種の作業には向いていないという意見がある
数か月後、より重いスタックから、より高性能だがやや風変わりなスタックへの移行が良い結果をもたらすのかについての続報が興味深いだろう
go-appの創始者がこの投稿を見つけて驚き、プロダクトの成功を願っている
Go WASMはJSONのパースが遅く、そのためアーキテクチャ変更と、WebSockets経由で段階的にデータをロードするための「スマートバックエンド」を作ることになった
WASMは特定のニッチな用途には適しているが、一般的なWebアプリを作るには不適切だという意見がある
すべての構成要素(フロントエンド/バックエンド/アプリ)で同じ言語を使うことには大きな価値があると考えている