3 points par GN⁺ 2024-03-29 | 1 commentaires | Partager sur WhatsApp
  • Le framework GUI Rust Dioxus 0.5 simplifie fortement le flux de développement web, desktop, mobile et Fullstack, autour d’une réécriture de dioxus-core et de la suppression de l’unsafe
  • Entre les versions 0.4.3 et 0.5.0, plus de 100 000 lignes de code et plus de 1 400 commits ont été ajoutés, avec un nouveau cœur conçu pour supprimer les durées de vie et la dépendance à Scope
  • La gestion d’état centrée jusque-là sur use_state et use_ref est remplacée par l’API Signal compatible Copy, ce qui réduit les Clone répétitifs dans les gestionnaires d’événements et les futures
  • Un flux unique avec dioxus::launch et dx serve --platform permet d’exécuter les applications web, desktop et Fullstack, le CLI transmettant automatiquement les build features adaptées à la plateforme cible
  • Le hot reload des assets, la réécriture du système d’événements, les améliorations du rendu desktop et le streaming des fonctions serveur élargissent encore le périmètre d’un codebase Rust unique

Orientation de la release Dioxus 0.5

  • Dioxus est une bibliothèque de création d’interfaces GUI en Rust, utilisée pour déployer des applications web, desktop et mobiles
  • La release 0.5 a été conçue pour répondre aux demandes de la communauté en matière de simplification, de robustesse et de maturité accrue
  • Principaux changements
    • réécriture complète de dioxus-core et suppression du code unsafe
    • introduction d’une API basée sur Signal à la place de use_state et use_ref
    • suppression de toutes les durées de vie et de l’état cx: Scope
    • une fonction launch unique pour démarrer l’application sur toutes les plateformes
    • hot reload des assets compatible Tailwind et CSS vanilla
    • réécriture des événements permettant l’accès aux types d’événements natifs WebSys
    • intégration d’Error Boundary, Server Future et Suspense
    • reconciliation desktop 5 fois plus rapide
    • streaming des fonctions serveur et hot reload Fullstack
  • Un guide de migration est disponible pour les utilisateurs passant de Dioxus 0.4

Suppression des durées de vie et de Scope

  • De Dioxus 0.1 à 0.4, les valeurs internes aux composants utilisaient la durée de vie 'bump, ce qui permettait d’utiliser hooks, props et scope dans les écouteurs d’événements sans copie
  • Cela fonctionnait globalement bien dans les gestionnaires d’événements, mais les futures de Dioxus devaient être 'static, ce qui imposait un clone avant de déplacer les valeurs dans une future
  • En cas d’erreur liée aux durées de vie, les messages pouvaient être déroutants, en indiquant par exemple que cx devait vivre plus longtemps que 'static, plutôt que de pointer le hook lui-même
  • Dioxus 0.5 supprime Scope et la durée de vie 'bump, et transforme Element en type sans durée de vie
  • Les composants peuvent désormais recevoir directement leurs props sans paramètre de scope
    • exemple : fn MyComponent(name: String) -> Element
  • Les fonctions runtime peuvent être appelées directement non seulement dans les composants, mais aussi dans les futures et les gestionnaires d’événements
  • Comme Element devient 'static, il peut aussi être utilisé dans les hooks ou fourni via l’API de contexte
  • Ce changement sert de base à des API plus simples à implémenter, comme les listes virtuelles ou le rendu hors écran

Suppression de l’unsafe dans dioxus-core

  • La suppression de la durée de vie 'bump et de scope a créé une opportunité de réduire le code unsafe interne à Dioxus
  • dioxus-core 0.5 ne contient aucun code unsafe
  • Une petite quantité d’unsafe subsiste dans certaines dépendances, que l’équipe Dioxus prévoit d’éliminer au cours du cycle de release 0.5
  • L’unsafe restant se répartit entre du code simplement supprimable et du code nécessaire à cause de la FFI

Gestion d’état basée sur Signal

  • Dioxus 0.5 introduit Signal comme type primitif central pour l’état des composants
  • Signal apporte deux avantages par rapport à use_state et use_ref
    • il est toujours compatible Copy
    • il ne nécessite pas d’abonnement manuel
  • État Copy

    • Signal<T> est Copy même si la valeur interne T ne l’est pas
    • Ce comportement est rendu possible par le crate generational-box, implémenté sans unsafe
    • Si nécessaire, Signal peut être rendu Send+Sync, pour être transféré entre threads
    • La combinaison d’un état Copy, de Signal en Send+Sync et de composants statiques permet de déplacer facilement l’état là où il est nécessaire : futures, gestionnaires d’événements, threads, etc.
    • Le mode d’utilisation mémoire reste proche de celui de la 0.4, sans nécessiter de Clone explicite
  • Abonnements intelligents

    • Signal détermine plus finement quels composants doivent être réexécutés quand une valeur change
    • Un composant n’est réexécuté que s’il a effectivement lu la valeur du Signal
    • Une lecture dans une tâche async ou un gestionnaire d’événement n’est pas traitée comme un abonnement de réexécution du composant
    • Si un parent modifie un Signal via un clic sur un bouton sans lire directement sa valeur, et qu’un enfant seul lit cette valeur, seul l’enfant est rerendu
    • Cette architecture rend inutile Fermi, qui était auparavant un crate de gestion d’état séparé
    • Fermi proposait une API proche de use_state en utilisant des static comme clés
    • Dans Dioxus 0.5, il suffit de placer un GlobalSignal dans un static et de l’utiliser comme un Signal ordinaire
    • Signal fonctionne aussi avec l’API de contexte, ce qui permet de partager l’état entre composants sans hook use_shared_state dédié
    • Si un Signal est lu dans des hooks comme use_future ou use_memo, il est automatiquement ajouté aux dépendances du hook

Hot reload du CSS et des assets

  • Dioxus 0.5 implémente le hot reload des fichiers CSS dans le répertoire d’assets, dans le cadre d’une refonte du système d’assets
  • Lorsqu’un fichier CSS apparaît dans le RSX, le CLI dx le surveille et diffuse immédiatement les mises à jour vers l’application en cours d’exécution
  • La fonctionnalité est prise en charge sur Web, Desktop et Fullstack ; le support mobile est prévu dans une future mise à jour centrée sur mobile
  • Utilisé avec le watcher Tailwind, cela active aussi le hot reload de Tailwind CSS
  • Dans VSCode, on peut aussi bénéficier du hinting des classes Tailwind via une extension regex personnalisée
  • Les changements peuvent être diffusés simultanément à plusieurs appareils pour déclencher le hot reload sur l’ensemble des cibles

Réécriture du système d’événements

  • Depuis son lancement, Dioxus utilisait un système de synthetic events pour proposer une API d’événements cross-platform
  • Les synthetic events sont utiles pour harmoniser le comportement entre plateformes et pour la sérialisation réseau, mais ils ont aussi leurs limites
  • Dioxus 0.5 expose désormais les types d’événements sous-jacents de chaque plateforme, tout en fournissant des traits pour l’API cross-platform
  • Cette évolution apporte deux avantages
    • il devient possible d’extraire directement les informations nécessaires depuis les types d’événements natifs ou de les transmettre à d’autres bibliothèques
    • le code d’événements non utilisé par l’application peut être exclu via bundle splitting
  • Sur un exemple hello world, la taille compressée en gzip diminue d’environ 25 %
  • Des conseils pour produire des bundles plus légers figurent dans le guide d’optimisation Dioxus

API d’exécution cross-platform

  • Dioxus 0.5 introduit une nouvelle API cross-platform pour lancer les applications
  • Au lieu d’importer des packages de renderer séparés, il suffit d’activer les features voulues dans le crate dioxus puis d’appeler la fonction launch du prelude
  • Une même application peut être lancée sur les plateformes suivantes
    • Desktop : dx serve --platform desktop
    • SPA Web : dx serve --platform web
    • Fullstack : dx serve --platform fullstack
  • Le CLI transmet automatiquement les build features appropriées en fonction de la plateforme cible

Bêta du système d’assets et Manganis

  • Avec Dioxus et les applications web, les chemins d’assets deviennent vite obsolètes, les liens peuvent différer entre desktop et web, et les assets à inclure dans le bundle doivent souvent être ajoutés manuellement
  • Les assets peuvent aussi devenir un goulot d’étranglement pour les performances
  • Dans l’exemple du guide Dioxus Mobile, la version 0.4 nécessitait 7 secondes de chargement et transférait 9 Mo de ressources
  • Le guide mobile en 0.5, avec les mêmes images, charge en moins d’une seconde et réduit d’un tiers les ressources nécessaires
  • Dioxus 0.5 introduit le nouveau système d’assets manganis
    • il s’intègre au CLI pour inspecter, bundler et optimiser les assets de l’application
    • son API est encore instable, ce qui explique sa distribution dans un crate séparé
    • si l’on encapsule un asset avec la macro mg!, le CLI le détecte automatiquement
    • plus de détails sont disponibles dans la documentation de manganis
  • L’équipe prévoit aussi d’ajouter le hot reload aux assets manganis pendant le cycle de release 0.5

Rendu desktop 5 fois plus rapide

  • Dioxus utilise plusieurs optimisations pour générer rapidement les diffs de rendu
  • Les Templates permettent au macro rsx! d’ignorer le diff des parties statiques
  • Sur Dioxus Web, sledgehammer permet d’appliquer rapidement les modifications du DOM depuis Rust
  • Dioxus 0.5 applique désormais la même logique aux changements envoyés via le réseau
  • Les renderers Desktop et LiveView communiquent les changements via un protocole binaire au lieu de JSON
  • Sur des charges de rendu élevées, le nouveau renderer réduit à un cinquième le temps d’application des changements dans le navigateur et divise par deux la latence
  • Un benchmark qui bloquait continuellement le renderer en Dioxus 0.4 s’exécute désormais de manière fluide en Dioxus 0.5

Fonctions de confort pour l’écriture de composants

  • Dioxus 0.5 permet d’étendre un élément donné et de propager des attributs vers cet élément
    • exemple : un composant ImgPlus qui étend les attributs d’un élément img peut recevoir directement des attributs classiques comme width, height ou src
  • Une syntaxe abrégée d’initialisation de structure peut être utilisée pour transmettre des valeurs aux attributs et aux composants
    • on peut écrire class au lieu de class: class
  • Les attributs abrégés fonctionnent avec tout élément implémentant IntoAttribute, y compris les Signal
  • Les attributs Signal n’évitent pas encore le diffing, mais cela devrait être ajouté dans le cadre d’optimisations de performance pendant le cycle 0.5
  • Les attributs répartis sur plusieurs lignes peuvent être fusionnés
    • si l’on ajoute des valeurs conditionnelles à un même attribut class, elles sont fusionnées en utilisant l’espace comme séparateur
    • c’est important pour des bibliothèques comme Tailwind, qui nécessitent à la fois une analyse à la compilation et un comportement dynamique à l’exécution
    • cette syntaxe s’intègre au compilateur Tailwind et supprime le surcoût runtime de bibliothèques comme tailwind-merge

Streaming des fonctions serveur et Fullstack

  • Dioxus 0.5 prend en charge la dernière version du crate server functions, compatible avec les données en streaming
  • Les fonctions serveur peuvent diffuser des données vers le client ou envoyer des données du client vers le serveur sous forme de flux
  • Une fonction serveur en streaming peut être créée en définissant son type de sortie, puis en renvoyant TextStream depuis la fonction serveur
  • Cela convient particulièrement aux traitements longs pendant lesquels il faut mettre à jour le client
  • Un exemple existe avec Kalosm et un LLM local pour proposer, sur du matériel courant, une fonctionnalité proche d’un endpoint OpenAI ChatGPT
  • Le CLI prend désormais en charge la plateforme fullstack et fournit le hot reload ainsi que des builds parallèles côté client et côté serveur
    • dx serve
    • dx serve --platform fullstack

LiveView, gestionnaires d’assets et traitement des fichiers

  • Dans Dioxus 0.5, le router fonctionne nativement dans les applications LiveView
  • Dioxus Desktop prend en charge des custom asset handlers
  • Ces custom asset handlers permettent de diffuser efficacement des données vers le navigateur depuis du code Rust, sans passer par JavaScript
  • C’est adapté aux communications à forte bande passante, comme le streaming vidéo
  • Il devient possible d’envoyer directement des données gstreamer ou webrtc vers la webview, ce qui réduit le besoin d’encoder et décoder soi-même les frames
  • Le glisser-déposer de fichiers sur desktop est aussi intégré nativement au système d’événements

Gestion des erreurs

  • Dioxus facilite la gestion des erreurs dans les composants parents via Error Boundary et le trait throw
  • L’approche throw combine les avantages d’un état d’erreur et du retour anticipé
  • Il est possible d’appeler throw sur un type Result implémentant Debug pour le convertir en état d’erreur, puis d’utiliser ? pour effectuer un retour anticipé
  • Le composant ErrorBoundary affiche un composant alternatif lorsqu’une erreur a été levée dans ses enfants
  • ErrorBoundary peut être imbriqué, ce qui permet de capturer les erreurs à plusieurs niveaux de l’application
  • Ce modèle est utile pour gérer un état d’erreur global sans provoquer de panic en cas d’erreur irrécupérable ni maintenir manuellement un état distinct pour chaque erreur

Expérience de développement et templates

  • Dioxus a introduit le hot reload en 0.3, l’a étendu au Desktop en 0.4, et l’active par défaut en 0.5
  • En lançant une application avec dx serve, le hot reload est activé par défaut en mode développement
  • Même lorsqu’un hot reload n’est pas possible sur une application Desktop et qu’une recompilation complète est nécessaire, l’état de la fenêtre ouverte est préservé et restauré
    • la taille et la position de la fenêtre sont conservées
    • cela réduit les situations où l’application repasse en plein écran à chaque modification
  • Les nouveaux templates ont été réorganisés pour permettre de créer des applications Web, Desktop, Mobile, TUI et Fullstack avec une seule commande
  • L’application par défaut de dx new se rapproche désormais de create-react-app
    • elle inclut les assets, le CSS et la configuration de déploiement de base
    • elle contient aussi des liens vers des ressources utiles comme dioxus-std, l’extension VSCode, la documentation et les tutoriels

Dioxus Community et l’écosystème

  • Dioxus Community a mis à jour des crates importantes de l’écosystème pour accompagner la release 0.5
  • Des crates comme icons, charts ou la bibliothèque standard dédiée à Dioxus sont prêtes à être utilisées dès la sortie de la 0.5
  • Le projet Dioxus Community est une nouvelle organisation GitHub destinée à maintenir les crates importantes à jour, même si leur maintainer d’origine se retire
  • Si vous développez une bibliothèque pour Dioxus, l’équipe peut aider à sa maintenance, avec l’objectif de fournir un support de fait de niveau « Tier 2 »

Fonctionnalités prévues ensuite

  • Après la 0.5, les plans incluent notamment
    • stabilisation et intégration plus poussée du système d’assets
    • bundle splitting direct de la sortie .wasm avec lazy component
    • Islands, interactivité resumable et sérialisation de Signal
    • fusion des server components et de LiveView dans Fullstack
    • amélioration des Devtools et du framework de test
    • refonte complète de Mobile
    • refonte de Fullstack avec WebSocket, SSE, progressive forms, etc.

Aperçu de Dioxus-Blitz basé sur Servo

  • Dans le cadre de « Blitz 2.0 », Dioxus-Blitz vise un rendu natif WGPU en intégrant Servo et en s’appuyant sur un moteur CSS comparable à celui utilisé pour faire tourner Firefox
  • Nico Burns, créateur de la bibliothèque de layout Taffy, a rejoint le projet à temps plein pour mener ce travail
  • Une démo montre le rendu de google.com sur GPU à 900 FPS
  • L’implémentation actuelle n’est pas encore complète et le rendu de google.com reste un peu maladroit, mais le projet progresse rapidement vers un niveau utilisable
  • Le dépôt est disponible à l’adresse https://github.com/jkelleyrtp/stylo-dioxus

Comment contribuer

  • Le projet Dioxus recherche des contributions sur les points suivants
    • traduction de la documentation
    • prise en charge des « Good First Issues »
    • amélioration de la documentation
    • contributions au CLI
    • réponses aux questions de la communauté sur Discord
  • L’équipe Dioxus remercie la communauté pour son soutien sur le reste de l’année 2024 et appelle à l’aide pour transformer le développement d’applications

1 commentaires

 
GN⁺ 2024-03-29
Avis sur Hacker News
  • L’an dernier, j’ai créé Ebou, un client Mastodon, avec Dioxus. Dans l’ensemble, l’expérience a été bonne, mais il manquait aussi beaucoup de choses.
    Quand j’ai commencé à travailler dessus, c’était la version 0.2, et avec les changements de cette 0.5, il semble que presque toute la complexité que j’avais rencontrée à l’époque ait disparu. Je ne l’ai pas encore essayé moi-même, mais la suppression des lifetimes et la réduction de l’obligation de cloner sans cesse devraient rendre l’expérience bien plus agréable.
    • Je serais curieux de savoir comment vous avez choisi Dioxus.
      Il existe pas mal de frameworks Rust qui visent une UI réactive native déployable sur desktop, web/wasm, mobile, etc. (https://github.com/flosse/rust-web-framework-comparison), et je crains qu’un mauvais choix oblige à maintenir un framework abandonné ou à subir une migration douloureuse.
      Il y a eu aussi beaucoup de frameworks de serveurs HTTP en Rust, et aujourd’hui Axum, Actix et Rocket semblent être en tête ; comme le mouvement de la communauté paraît se déplacer vers Axum, je me demande parfois si choisir Actix était une erreur. Je voudrais savoir s’il existe des signes que Dioxus va l’emporter, ou des indicateurs permettant de le choisir aujourd’hui au-delà d’une grande communauté, du soutien de YC et de la dynamique.
      J’aimerais aussi savoir si Leptos et Yew sont aussi des concurrents majeurs, et en quoi ils sont meilleurs ou moins bons que Dioxus. Notre entreprise a beaucoup investi dans Rust, Actix et Bevy, et nous voulons à l’avenir associer des frameworks comme Bevy et Dioxus pour créer des clients desktop et mobiles natifs.
      Et je me demande aussi si le nom Dioxus vient du Deoxys de Pokémon. Le logo donne cette impression, mais il n’y a aucune référence à Pokémon dans la base de code.
  • Je suis d’accord avec « dans l’ensemble, c’était bien, mais il manquait beaucoup de choses ».
    Il y a environ 9 mois, j’ai créé un front-end GUI pour sshfs avec Dioxus, et jusqu’au moment où je me suis heurté à un mur parce qu’une fonctionnalité n’était pas encore terminée par les développeurs, j’avais vraiment l’impression que c’était un excellent framework GUI.
    Le partage d’état entre différents contextes est aussi parfois pénible, mais c’est le cas de tous les frameworks GUI que j’ai utilisés, quels que soient le langage ou la technologie sous-jacente. Dioxus 0.5 semble représenter un grand progrès sur ce point. Mon blog rend une bonne partie du HTML avec Dioxus, et comme ce n’est pas un usage qui pousse le framework dans ses retranchements, cela fonctionne très bien.
  • Je suis Dioxus avec intérêt, mais je n’ai pas encore eu l’occasion de l’essayer.
    Cela dit, la solution de suppression des lifetimes me laisse un peu perplexe. generational-box ressemble à une sorte de ramasse-miettes du pauvre ; je me demande quel a été l’impact sur les performances.
    Au passage, le lien [generational-box]([https://crates.io/crates/generational-box](<https://crates.io/crates/generational-box>;)) est cassé.
    • C’est bien un ramasse-miettes du pauvre, mais la sémantique mémoire est exactement la même que dans les versions précédentes.
      use_hook possède la valeur pendant toute la durée de vie du composant, donc lorsque le composant disparaît, cette valeur est également droppée. Tous les signals utilisent toujours use_hook, donc leur lifetime est identique. Appeler GenerationalBox::new() en dehors de use_hook n’est généralement pas recommandé, il n’y a donc pas d’impact sur les performances.
      Si vous abusez de GenerationalBox::new() dans une boucle, ces déchets resteront jusqu’à ce que le composant soit droppé, mais la plupart des gens feront plutôt des push/pop dans une Map ou un Vec, et dans ce cas la sémantique mémoire habituelle s’applique.
    • C’est essentiellement du comptage automatique de références : https://en.wikipedia.org/wiki/Automatic_Reference_Counting
  • Je ne suis pas programmeur Rust, mais je me demande comment fonctionne le crate generational-box.
    Je comprends que c’est une forme d’allocation en arène, mais je ne vois pas comment cela prend en charge la « copie sans copie », ni pourquoi il est sûr de dire qu’en interne on crée une arène de RefCell avec des générations et que GenerationalBox est Copy.
    Je comprends qu’on puisse créer des pointeurs vers des données statiques, mais je me demande ce qu’il se passe pour des valeurs qui n’ont pas une durée de vie statique.
    • On ne copie pas les données, on copie une référence aux données.
      La référence aux données reste valable pendant toute la durée de vie du programme. La generational box permet d’y placer des données qui vivent moins longtemps que le programme, mais ces données ne doivent pas contenir de références. Lorsque les données insérées sont droppées, la box est réutilisée pour une autre allocation.
      À part le fait d’utiliser des boxes plutôt qu’une arène centralisée, l’approche est très proche d’une arène générationnelle ; c’est un choix fait pour éviter les problèmes de verrouillage. Si l’on tente d’accéder aux données via une référence Copy après leur drop, cela échoue avec un bon message d’erreur.
    • Je ne connais pas bien ce crate, mais du point de vue de Rust, Copy a un sens précis.
      Si un type implémente le trait Copy, cela signifie qu’il peut être copié avec memcpy, et qu’il s’agit plutôt d’une copie superficielle que d’une copie profonde.
      Donc je le comprends non pas comme une « copie sans copie », mais comme le fait de pouvoir traiter un type non Copy comme un type Copy. Le README indique qu’un contenu statique est nécessaire, donc pour une valeur sans lifetime statique, la réponse est : « on ne peut pas faire cela ».
  • Je suis le projet depuis un moment et je suis très content de voir cette sortie.
    J’aime le fait que Dioxus reprenne beaucoup des éléments qui ont fait le succès de React, tout en innovant et en livrant rapidement par-dessus. J’ai hâte d’essayer les signals de cette version.
  • J’aimerais qu’au lieu de RSX, ce soit quelque chose de plus proche de SwiftUI que de React/JSX.
    Je reconnais les bonnes choses que React a apportées à JS et au web, ainsi que la force de son nom, mais si l’on peut concevoir un langage ou un DSL depuis zéro en 2024, je ne pense pas que le code d’« UI réactive » doive forcément ressembler à React.
    Je ne dis pas que SwiftUI est parfait, mais le code écrit avec SwiftUI me semble beaucoup plus proprement organisé et compartimenté que du code équivalent en React.

Le vrai avantage d’utiliser JSX pour des GUI cross-platform, c’est surtout de pouvoir réutiliser des bibliothèques existantes pour le web ; avec RSX, à part permettre aux développeurs de transférer leur connaissance des concepts de JSX vers RSX, la « valeur portable » me semble limitée. À la limite, le meilleur compromis serait d’apprendre un nouveau paradigme objectivement supérieur à celui de React/JSX.
En résumé, ce serait bien d’avoir un projet qui soit « SwiftUI, mais cross-platform », mais ça n’existe pas encore. Je connais @Tokamak/TokamakUI, mais il est encore très incomplet et son activité semble avoir diminué.

  • Il y a https://ribir.org/
    Pour l’instant, il ne prend en charge que les applications desktop natives Linux/mac/windows, mais la prise en charge de WASM, du web et du mobile est prévue.
  • J’ai choisi Dioxus pour créer la page d’accueil décentralisée de Freenet.
    Ce sera le premier site web décentralisé que verront les personnes qui auront configuré Freenet. C’est un peu similaire à Kweb, le framework web Kotlin sur lequel je travaille par intermittence depuis quelques années, notamment dans la gestion de l’état et dans l’approche DSL qui mappe le code vers du HTML. Jusqu’ici, ça me plaît.
    https://freenet.org/
    https://kweb.io/
    • Génial. Je crois que j’avais regardé kweb quand j’ai conçu le DSL au départ, et les deux sont vraiment similaires.
      En fait, je suis fan de Kotlin, et j’aime les DSL Kotlin ainsi que son modèle de concurrence.
  • Je me demande comment ça se compare à Tauri.
    • Nous avons ajouté ça dans le README : https://github.com/dioxusLabs/dioxus/?tab=readme-ov-file#dioxus-vs-tauri
      Tauri place le frontend dans une webview, et il faut communiquer avec les fonctions Rust natives via une frontière IPC, comme avec Electron.
      Dans Dioxus, le code Rust est côté natif, donc pas besoin d’IPC pour des opérations comme lire le système de fichiers ou utiliser des websockets. Tauri oblige à compiler le frontend en WASM, et beaucoup de crates Rust intéressantes ne se compilent pas en wasm.
      Il est difficile d’exprimer à quel point le développement devient plus simple sans frontière IPC. Les outils Dioxus ne ciblent que Rust, donc on peut passer de zéro à un .app packagé en moins d’une minute. Un nouveau build prend environ 12 secondes, un nouveau bundle environ 20 secondes.
      Cela dit, j’apprécie beaucoup la flexibilité offerte par Tauri, c’est-à-dire la possibilité d’utiliser comme frontend n’importe quelle UI compatible web, et on peut aussi utiliser Dioxus dans une application Tauri.
    • J’étais venu poser la même question.
      C’est bien que Dioxus l’aborde directement dans le README, mais j’aimerais aussi connaître l’expérience réelle de personnes ayant utilisé les deux.
      J’ai créé une application desktop jouet avec Tauri, et j’ai vérifié si l’IPC était assez rapide pour que le frontend web se mette à jour et travaille à chaque frappe sans latence : la réponse était « oui ». Quant à savoir si l’on peut envoyer un gros fichier du frontend vers la couche Rust à chaque frappe, puis le renvoyer au frontend, la réponse était « non », du moins avec mon implémentation naïve.
      Tauri comme Dioxus ont beaucoup de bons cas d’usage, et dans certains cas Dioxus semble meilleur. J’aimerais lire des retours comparatifs du type « dans notre projet, nous avons choisi Dioxus ou Tauri à cause de X et Y ». Dioxus a vraiment l’air super, j’ai hâte de l’essayer.
  • Je me demande comment les applications natives sont rendues. Est-ce que ça tourne toujours dans une sorte d’instance de navigateur ?
    • On peut utiliser la webview du système comme moteur de rendu, ou choisir un moteur expérimental basé sur WGPU qui intègre stylo.
      stylo est la partie de Servo partagée avec Firefox. À long terme, nous aimerions orienter les gens vers le renderer WGPU, mais il en est encore à un stade assez précoce, et beaucoup d’entreprises qui utilisent Dioxus savent pragmatiquement que la webview est une solution suffisamment bonne pour environ 90 % des applications.
  • Concernant le passage « pendant le cycle de release 0.5, nous prévoyons de supprimer les toutes petites portions d’unsafe restantes dans plusieurs dépendances », j’aimerais voir quels sont ces usages et quelle est la motivation.
    Je comprends que les gens utilisent parfois unsafe trop facilement, mais la bibliothèque standard est elle aussi remplie de unsafe, et tracer la ligne à cet endroit ressemble parfois à tracer une ligne dans le sable.
    • C’est surtout nécessaire pour interagir avec du FFI ou pour déclarer certains types comme Send/Sync.
      Il y a trois usages. Des corrections FFI pour iOS, une implémentation permettant la syntaxe d’appel de fonction sur les signals, et l’implémentation de Send/Sync pour un ID qui utilise un pointeur comme hash.
      Pour le dernier, maintenant que j’y repense, on pourrait peut-être le remplacer par un usize et le supprimer.
    • Je suis d’accord sur le fait que les gens peuvent avoir un peu trop peur de unsafe.
      Cela dit, viser la suppression de unsafe dans sa propre crate n’est pas forcément un mauvais choix de la part d’un auteur de crate.
      Les auteurs de crates qui cherchent à éliminer tout unsafe essaient souvent de réduire la charge de confiance qui pèse sur les utilisateurs. C’est, à mon avis, la force du mot-clé unsafe. En réalité, il aurait peut-être fallu le diviser en blocs trust_me et en fonctions check_yourself.
      unsafe limite les discussions sur la sûreté mémoire à des endroits très restreints et auditables du code, tout en créant une nouvelle conversation sur la confiance, plus gérable.
  • Je comprends pourquoi React a créé la convention de nommage use* pour l’API des hooks, mais je me demande pourquoi, dans Dioxus, la fonction qui crée un nouveau signal s’appelle use_signal.
    let mut count = use_signal(|| 0);, ce n’est pas un appel qui crée un nouveau signal ? Le signal n’est pas recréé à chaque rendu, et c’est précisément le principe d’un signal.
    Dans SolidJS, on crée un signal avec createSignal, comme dans const [count, setCount] = createSignal(0), et c’est beaucoup plus facile à comprendre.
    Les noms d’API sont importants, parce que les hooks d’état se comportent différemment et peuvent entraîner le besoin de compléments comme useMemo. Je me demande s’il y a une raison au choix du nom use_signal, au-delà du fait que Dioxus veuille ressembler à React.
    • Dioxus continue bien à rerender les composants, mais applique beaucoup d’optimisations au rsx produit par le composant, ce qui donne des performances proches de Solid.
      Il est plus proche de Preact que de Solid.
      Les optimisations incluent la séparation des fragments dynamiques de l’UI dans des « diff bins » distincts, la mémoïsation par défaut, et le fait que les signals marquent implicitement les propriétés comme dirty/managed.