作者丨 Alex Suraci
译者丨明知山
策划丨李冬梅
几周前,我们正式推出 Dagger Cloud v3,全新的 Dagger Cloud 用户界面。v3 与 v2 之间一个显著的区别在于,新的用户界面是用 Go 语言编写,并基于 WebAssembly(WASM)实现的。乍看之下,这似乎是一个不同寻常的选择——在开发 Web UI 时,Go 通常不是人们首先想到的语言——但我们有充分的理由。在这篇博文中,我将详细阐述我们选择 WebAssembly 的原因,我们在实现过程中遇到的挑战(以及我们是如何解决的这些问题)以及最终的结果。
两套代码库 = 更多的工作量,更少的功能
Dagger 的工作原理是构建操作的有向无环图(DAG),并对其进行评估(通常是并行评估)。本质上,这是一个很难直观展示的过程。为了帮助用户更好地理解,我们提供了两种实时可视化界面:Dagger Terminal UI(TUI),包含在 Dagger CLI 中,以及 Dagger Cloud,一个在线 Web 仪表盘。Dagger TUI 是用 Go 实现的,而 Dagger Cloud(v3 之前)是用 React 编写的。
我们希望这两个用户界面尽可能保持一致。然而,实时解析 Dagger 事件流并生成用户界面的过程相当复杂。在一些更复杂的场景中,事件流可能包含数十万个 OpenTelemetry Span 数据,管理这些数据结构的复杂性会迅速攀升。这导致 Web UI 常常因数据量过大而变得卡顿和缓慢。为了解决这一性能瓶颈,我们不得不为 React 应用程序采用一种不同的实现方式。
因此,我们最终有了两个实现相同目标的界面,一个使用 TypeScript 和 React 语言及生态系统,另一个则使用完全不同的语言和生态系统(Go)。我们无法在这两者之间轻松地共享业务逻辑。作为一个小团队,我们需要快速交付功能,不得不为每个功能分别实现两次,这对我们的开发速度造成了巨大的阻碍。
我们开始考虑一种新的方法,主要要达成两个目标:
Go + WebAssembly
我们的初步目标是让 Dagger Cloud 和 TUI 共享同一个代码库。我们很早就决定采用 Go 代码库。从技术上讲,我们也可以反过来,使用 TypeScript 开发 TUI,但考虑到我们主要是 Go 工程师团队,选择 Go 能让其他成员更容易参与其中,无论是添加新功能还是帮忙调试问题。除了统一为一种语言外,这一选择还为我们带来了灵活性,打破了团队内部的隔阂。
既然我们决定直接在浏览器中运行 Go 代码,WebAssembly 就成了顺理成章的选择。但这仍然带来了一些挑战:
降低项目风险
接下来的问题便是:“我们该如何构建它?”我们选择使用 go-app(https://go-app.dev/)框架开发新的基于 WebAssembly 的用户界面。go-app 是一个专为 WebAssembly 渐进式 Web 应用程序(PWA)设计的高级框架。它保留了 Go 语言的核心优势,例如快速编译和原生静态类型支持,同时采用了基于组件的用户界面模型,与 React 类似,这使得迁移过程变得更加容易。
由于 Go + WebAssembly 组合并不是主流,Dagger 团队内部对其可行性自然存在一些怀疑。例如,目前没有真正成熟的 go-app UI 组件生态系统,我们不得不自行开发,但我们不清楚这一过程会有多容易或多困难。我们还担心与其他服务(Tailwind、Auth0、Intercom、PostHog)的集成,以及同时渲染数百个需要实时更新的组件的性能问题。
为了回答这些问题并降低项目风险,我花了将近一个月的时间进行原型设计,目标是尽可能多地使用 go-app 重新实现现有的用户界面。事实证明,我们没有遇到太多障碍:WebAssembly 已经是一个文档完备的开放标准,而大多数其他问题都可以在 go-app 的文档中找到答案。正如预期的那样,最大的挑战是内存使用限制,这需要进行精心的设计和优化。
从原型到生产
在成功完成一个可行的概念验证后,团队的信心大幅提升,我们随即启动了“awesome wasm”项目,致力于打造一个生产级的实现。以下是这段旅程的一些关键要点:
几周前,我们向 Dagger 指挥官们推出了 Dagger Cloud v3,用以收集反馈,并计划在不久后向所有人正式开放。
优势分析
从 React 切换到 WASM,不仅使所有 Dagger 界面的用户体验更加一致,还在渲染大型和复杂的追踪信息时实现了更高的整体性能和更低的内存使用。
从工程角度来看,这也为我们团队带来了显著的好处。优化工作往往与实际实现功能的工作量相当,甚至更多。我们因此能够避免分别优化 Web UI 和 TUI,而是将精力集中在交付新功能上,实在是令人欣慰。
你们也应该这么做吗?
Dagger Cloud v3 在 Dagger 社区引起了热议,最近我们被问到的一个较多的问题是:谁应该考虑这种技术,谁又不适合?
我们想强调的是,我们并不是推荐普遍都用 Go 开发前端。我们之所以选择这条路线,是基于一系列具体且充分的理由:我们拥有一支出色的 Go 工程师团队;面对一个复杂且难以用 TypeScript/React 扩展的 UI;需要在两个代码库之间实现标准化和代码复用;以及在公司范围内整体提升开发速度的要求。这确实是一个相当特殊的情况。如果你也有类似的情况,那么这种方案当然值得考虑。但如果你的情况有所不同,那么或许应该优先考虑其他更通用的工具和标准。
原文链接:
https://dagger.io/blog/replaced-react-with-go
声明:本文由 InfoQ 翻译,未经许可禁止转载。