-
거실 기기용 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 구성 단위
-
Signal과 Effect 기반의 반응형 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 생태계는 아직 발전 중이지만, 실서비스에서 충분히 실현 가능
- 성공적인 도입은 철저한 프로토타이핑과 점진적 이행 전략에 기반함