- Dagger Cloud v3를 출시하면서 새로운 UI는 WebAssembly(WASM)와 Go로 작성
- Go는 일반적으로 웹 UI 개발에 사용되지 않지만, "코드베이스 통합 및 성능 최적화"를 위해 이 방식을 선택
- 이 글에서는 "선택의 배경, 구현 과정에서의 도전 과제 및 최종 결과"를 공유
기존 문제: 두 개의 코드베이스로 인한 비효율
- Dagger는 DAG(Directed Acyclic Graph) 기반으로 동작하며, 이를 TUI(터미널 UI) 와 웹 대시보드(Dagger Cloud) 에서 시각화 제공
- 기존에 TUI는 Go, 웹 UI는 React/TypeScript로 구현됨
- 하지만 두 UI 간의 동기화가 어려웠고, 특히 웹 UI는 대량의 데이터를 실시간으로 처리하는 데 성능 문제가 발생함
- 복잡한 OpenTelemetry 이벤트 스트림(수십만 개의 스팬)을 처리하면서 React UI의 성능 저하 및 속도 문제가 두드러짐
- 동일한 기능을 두 번 구현해야 했으며, 이는 작은 팀에게 큰 개발 부담이었음
- 따라서, 코드베이스 통합 및 성능 최적화를 목표로 새로운 접근 방식을 고려
선택한 해결책: Go + WebAssembly
-
Go로 코드베이스 통합
- TUI가 이미 Go로 구현되어 있어 웹 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와 웹 UI가 동일한 코드베이스를 사용하면서 더 일관된 UX 제공
-
성능 및 메모리 사용량 개선
- 대량의 데이터를 다룰 때 렌더링 속도 개선 및 메모리 사용량 감소
-
팀 생산성 향상
- 기존에는 Web UI와 TUI를 각각 최적화해야 했으나,
이제는 한 번의 최적화로 두 인터페이스에 동시에 적용 가능
- 덕분에 새로운 기능 개발에 더 집중 가능
Go + WASM으로 전환해야 할까?
-
일반적으로는 추천하지 않음, 하지만 특정 조건에서는 유용할 수 있음:
- Go 개발자가 많은 팀
- TypeScript/React가 성능 한계를 보이는 복잡한 UI
- TUI 및 Web UI 간 코드 공유 필요
- 개발 속도를 극대화해야 하는 환경
-
위 조건에 부합한다면 Go + WASM이 좋은 대안이 될 수 있음
하지만, 대부분의 경우 기존 웹 기술(React, TypeScript 등)이 더 적합