아마존 Prime Video, 거실 디바이스 UI를 Rust + WebAssembly로 전면 재구축

3 weeks ago 5

  • 거실 기기용 UI를 Rust와 WebAssembly 기반으로 전면 재구성한 사례
  • 다양한 성능 수준의 기기에서도 고성능과 낮은 입력 지연을 실현하기 위한 구조를 설계
  • React 기반에서 벗어나 Rust 전용 UI SDK를 자체 개발, 높은 생산성 확보
  • Entity-Component-System (ECS) 기반의 아키텍처를 통해 코드 복잡도와 성능 관리
  • WebAssembly와 Rust의 사용으로 인한 장단점 및 문제점에 대한 솔직한 분석

Prime Video UI를 Rust와 WebAssembly로 재구성한 이유

  • Amazon은 다양한 거실 기기(콘솔, 셋톱박스, 스트리밍 스틱, TV 등) 에서 동일한 Prime Video 앱을 실행해야 하는 과제를 가짐
  • 다양한 성능을 가진 디바이스에서 일관된 사용자 경험을 제공하려면 고성능의 UI 엔진이 필수였음
  • 기존에는 React(TypeScript), JavaScript, C++, WebAssembly, Rust의 혼합 기술 스택을 사용
  • JavaScript의 느린 실행 속도와 업데이트 어려움으로 인해 전면 Rust로 이전 결정
  • WebAssembly를 활용하면 앱 업데이트가 쉬워지고, Rust는 성능 최적화에 유리함

거실 기기의 주요 개발 도전과제

  • PS5 같은 고성능 장치부터 저전력 USB 스틱까지 다양한 성능 스펙 대응 필요
  • 각 기기마다 별도 팀을 두지 않고 단일 코드 베이스로 개발해야 함
  • 대부분의 기기에서는 앱스토어 없이 펌웨어 업데이트만 가능하므로 네이티브 코드 업데이트가 어려움
  • UI를 자주 업데이트하려면 JavaScript 및 WebAssembly 기반 코드 사용이 유리함
  • 고성능 요구와 빠른 업데이트 주기의 균형점으로 Rust + WebAssembly 조합 선택

기존 아키텍처와 새로운 Rust 기반 UI 아키텍처 비교

  • 기존 아키텍처는 다음과 같은 구조:
    • React로 UI 로직 작성, Rust(WebAssembly)는 낮은 수준의 UI 엔진 처리
    • React → 메시지 버스 → WebAssembly UI 엔진 → C++ 렌더링 백엔드
  • 입력 지연 문제 해결을 위해 모든 비즈니스 로직을 Rust UI SDK로 마이그레이션
  • 새로운 아키텍처:
    • UI SDK부터 렌더링까지 전부 Rust로 구성
    • 메시지 버스 제거, 모든 처리 과정을 WebAssembly 내부에서 실행
    • 코드가 WebAssembly로 컴파일되어 TV로 전송되며, 기존보다 업데이트 속도 및 반응성 향상

새로운 Rust UI SDK의 주요 구성 요소

  • React와 유사한 컴포저블(Composable) 개념 도입 → 재사용 가능한 UI 구성 단위
  • SignalEffect 기반의 반응형 UI 시스템
    • Signal: 값이 변경되면 관련된 Effect를 트리거함
    • Memo: 이전 값과 달라졌을 때만 반응
  • UI 계층 구조는 compose! 매크로를 통해 정의
  • UI 요소는 Widget(기본 제공 컴포넌트)과 Composables(사용자 정의 구조)로 구성
  • Entity-Component-System(ECS) 아키텍처 사용:
    • Entity: ID
    • Component: 속성 데이터 (ex. Layout, RenderInfo, Text)
    • System: 특정 Component 조합에 대해 로직을 수행하는 함수

ECS 시스템 구조와 동작 방식

  • 각 시스템은 특정 컴포넌트 조합을 필요로 하며, 이를 기반으로 UI 업데이트 처리
  • 예시:
    • Resource Management System: 이미지 컴포넌트 → GPU 업로드 → RenderInfo 업데이트
    • Layout System: 다양한 레이아웃 관련 컴포넌트 계산
    • Rendering System: RenderInfo 기반으로 실제 화면 출력
  • 이 구조를 통해 다양한 페이지를 React에서 Rust로 점진적으로 마이그레이션 가능
  • JavaScript 기반 페이지와 Rust 기반 페이지의 공존 및 전환이 원활

좋은 결과와 이점

  • JavaScript/React 개발자도 Rust UI SDK로 생산성 손실 없이 전환 성공
  • UI SDK의 친숙한 구조 덕분에 러스트 초심자도 빠르게 적응 가능
  • 레이아웃 애니메이션, 빠른 화면 전환 등 이전엔 불가능했던 기능 구현 가능
  • 내부 개발 도구(리소스 매니저, 레이아웃 인스펙터 등)도 Rust 기반으로 신속하게 제작 가능
  • 250ms였던 입력 지연을 33ms까지 대폭 감소 (저사양 기기 기준)

어려웠던 점과 기술적 한계

  • WebAssembly System Interface(WASI) 는 아직 발전 중인 생태계로, Rust 업데이트 시 기존 코드가 깨질 가능성 존재
  • WebAssembly에서는 panic 발생 시 앱 전체 종료 → 안정성 확보에 어려움
    • JavaScript와 달리 예외 처리 미흡 → Result 타입 적극 활용 필요
    • 외부 라이브러리 의존 시 panic-free 구현 유도 필요
  • 브라우저 환경에서는 WebAssembly 및 특정 렌더링 API가 미지원되어 웹 클라이언트에는 미적용

Bytecode Alliance와 생태계 기여

  • Amazon은 Bytecode Alliance의 일원으로 WASI 표준화와 관련 기능 개선에 적극 참여
  • 사용 중인 WebAssembly Micro Runtime은 C 기반이며, Rust 기반인 Wasmtime도 병행 검토
  • WebAssembly 생태계 발전을 위해 직접 기술 피드백 및 개발 참여 중

기타 Q&A

  • 웹 브라우저에서도 가능한가? → 일부 WebKit 브라우저는 WASM 미지원, 성능 저하, 구현 복잡성으로 아직은 고려 중
  • WebGL로 구현은 가능하지만 현재로선 투자 대비 효과가 낮아 보류

요약

  • Prime Video의 Rust+WebAssembly 기반 UI는 고성능, 낮은 입력 지연, 빠른 업데이트라는 3박자를 만족
  • 자체 UI SDK와 ECS 아키텍처는 복잡한 UI 동작을 효율적으로 관리
  • Rust 도입이 쉽지 않지만, 체계적인 설계와 개발 문화로 생산성과 안정성을 동시에 달성
  • WebAssembly 생태계는 아직 발전 중이지만, 실서비스에서 충분히 실현 가능
  • 성공적인 도입은 철저한 프로토타이핑과 점진적 이행 전략에 기반함

Read Entire Article