8 points par GN⁺ 2025-04-14 | 2 commentaires | Partager sur WhatsApp
  • Exemple de refonte complète d’une UI pour appareils de salon sur une base Rust et WebAssembly
  • Une architecture conçue pour offrir hautes performances et faible latence d’entrée même sur des appareils aux niveaux de performances très variés
  • Abandon de l’approche basée sur React au profit d’un SDK UI dédié en Rust développé en interne, avec un fort gain de productivité
  • Gestion de la complexité du code et des performances grâce à une architecture Entity-Component-System (ECS)
  • Analyse franche des avantages, inconvénients et problèmes liés à l’utilisation de WebAssembly et Rust

Pourquoi reconstruire l’UI de Prime Video avec Rust et WebAssembly

  • Amazon devait relever le défi de faire fonctionner la même application Prime Video sur divers appareils de salon (consoles, décodeurs, clés de streaming, TV, etc.)
  • Pour offrir une expérience utilisateur cohérente sur des appareils aux performances très différentes, un moteur d’UI très performant était indispensable
  • L’architecture existante reposait sur une stack technologique mixte combinant React (TypeScript), JavaScript, C++, WebAssembly et Rust
  • En raison de la lenteur d’exécution de JavaScript et des difficultés de mise à jour, la décision a été prise de migrer entièrement vers Rust
  • WebAssembly facilite la mise à jour de l’application, et Rust est particulièrement adapté à l’optimisation des performances

Principaux défis de développement pour les appareils de salon

  • Il fallait prendre en charge une large gamme de niveaux de performances, depuis des appareils puissants comme la PS5 jusqu’à des clés USB basse consommation
  • Le développement devait se faire sur une base de code unique, sans équipe distincte pour chaque appareil
  • Sur la plupart des appareils, seules les mises à jour de firmware sont possibles, sans app store, ce qui complique les mises à jour de code natif
  • Pour mettre à jour fréquemment l’UI, l’utilisation de code JavaScript et WebAssembly est plus avantageuse
  • Le choix de la combinaison Rust + WebAssembly représente un compromis entre fortes exigences de performance et cycle de mise à jour rapide

Comparaison entre l’ancienne architecture et la nouvelle architecture UI basée sur Rust

  • L’ancienne architecture était structurée comme suit :
    • logique UI écrite en React, moteur d’UI bas niveau géré en Rust (WebAssembly)
    • React → bus de messages → moteur d’UI WebAssembly → backend de rendu C++
  • Pour résoudre les problèmes de latence d’entrée, toute la logique métier a été migrée vers le SDK UI Rust
  • Nouvelle architecture :
    • de l’UI SDK jusqu’au rendu, tout est construit en Rust
    • suppression du bus de messages, tout le traitement s’exécute à l’intérieur de WebAssembly
    • le code est compilé en WebAssembly puis envoyé vers la TV, avec une meilleure vitesse de mise à jour et une meilleure réactivité qu’auparavant

Principaux composants du nouveau SDK UI Rust

  • Adoption d’un concept de Composable similaire à React → des unités de composition UI réutilisables
  • Système d’UI réactif basé sur Signal et Effect
    • Signal : lorsqu’une valeur change, il déclenche les Effect associés
    • Memo : ne réagit que si la valeur diffère de la précédente
  • La hiérarchie UI est définie via la macro compose!
  • Les éléments d’UI se composent de Widget (composants fournis) et de Composables (structures définies par l’utilisateur)
  • Utilisation d’une architecture Entity-Component-System (ECS) :
    • Entity : ID
    • Component : données d’attributs (ex. Layout, RenderInfo, Text)
    • System : fonction exécutant une logique sur une combinaison donnée de Component

Structure et fonctionnement du système ECS

  • Chaque système requiert une combinaison spécifique de composants et s’appuie dessus pour traiter les mises à jour de l’UI
  • Exemples :
    • Resource Management System : composant image → upload GPU → mise à jour de RenderInfo
    • Layout System : calcul de divers composants liés au layout
    • Rendering System : affichage réel à l’écran à partir de RenderInfo
  • Cette structure permet une migration progressive de différentes pages de React vers Rust
  • La coexistence et la transition entre pages basées sur JavaScript et pages basées sur Rust se font sans difficulté

Résultats positifs et avantages

  • Même les développeurs JavaScript/React ont pu passer au SDK UI Rust sans perte de productivité
  • Grâce à la structure familière du SDK UI, même les débutants en Rust peuvent s’adapter rapidement
  • Il est désormais possible d’implémenter des fonctionnalités auparavant impossibles, comme les animations de layout et les transitions d’écran rapides
  • Les outils internes de développement (resource manager, layout inspector, etc.) peuvent eux aussi être créés rapidement sur une base Rust
  • La latence d’entrée est passée de 250 ms à 33 ms (sur les appareils les moins puissants)

Difficultés rencontrées et limites techniques

  • WebAssembly System Interface (WASI) reste un écosystème en évolution, avec un risque que des mises à jour de Rust cassent du code existant
  • Dans WebAssembly, un panic met fin à toute l’application, ce qui complique la garantie de stabilité
    • contrairement à JavaScript, la gestion des exceptions est insuffisante → nécessité d’utiliser activement le type Result
    • en cas de dépendance à des bibliothèques externes, il faut encourager des implémentations sans panic
  • Dans l’environnement navigateur, WebAssembly et certaines API de rendu ne sont pas prises en charge, donc cette approche n’est pas appliquée au client web

Bytecode Alliance et contribution à l’écosystème

  • Amazon participe activement, en tant que membre de la Bytecode Alliance, à la standardisation de WASI et à l’amélioration des fonctionnalités associées
  • Le WebAssembly Micro Runtime utilisé est basé sur C, et Wasmtime, basé sur Rust, est également étudié en parallèle
  • Amazon contribue directement à l’évolution de l’écosystème WebAssembly via des retours techniques et une participation au développement

Autres Q&R

  • Est-ce possible aussi dans un navigateur web ? → certains navigateurs WebKit ne prennent pas en charge WASM, les performances baissent, et la complexité d’implémentation reste élevée, donc cela est encore à l’étude
  • Une implémentation avec WebGL est possible, mais le rapport coût/bénéfice est jugé insuffisant pour le moment, donc l’idée est mise en attente

Résumé

  • L’UI de Prime Video basée sur Rust + WebAssembly réunit hautes performances, faible latence d’entrée et mises à jour rapides
  • Le SDK UI maison et l’architecture ECS permettent de gérer efficacement des comportements UI complexes
  • Même si l’adoption de Rust n’est pas simple, une conception méthodique et une culture de développement adaptée permettent de concilier productivité et stabilité
  • L’écosystème WebAssembly est encore en développement, mais il est déjà suffisamment viable pour un service réel
  • Cette adoption réussie repose sur un prototypage rigoureux et une stratégie de migration progressive

2 commentaires

 
seunggi 2025-04-14

Par rapport au front-end qui embarque par défaut une bibliothèque de gestion d’état, j’ai tendance à penser que le jeu, justement, fonctionne un peu en mode « à la dure ? », puisque tous les états interagissent avec tous les autres. À l’inverse, utiliser l’ECS dans une application revient sans doute à adopter une gestion d’état modélisée, un peu comme quand chaque développeur utilise ses propres patterns ou une bibliothèque interne ; je serais curieux de savoir comment cet aspect a été traité.

 
y15un 2025-04-14

Appliquer à l’UI un ECS qu’on voyait plutôt dans les moteurs de jeu, voilà une idée assez originale. Aujourd’hui encore, j’aurai appris quelque chose.