Dagger가 React 프론트엔드를 Go + WebAssembly로 전환한 이유

2 weeks ago 3

  • 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 등)이 더 적합

Read Entire Article