3 ポイント 投稿者 GN⁺ 2024-03-29 | 1件のコメント | WhatsAppで共有
  • Rust GUIフレームワーク Dioxus 0.5 は、dioxus-core の書き直しと unsafe の排除を中心に、Web・デスクトップ・モバイル・Fullstack 開発の流れを大きく簡素化
  • 0.4.3 から 0.5.0 までの間に 10万行以上 のコードと1,400件以上のコミットが入り、新しいコアはライフタイムと Scope への依存をなくす方向に変更
  • 従来の use_stateuse_ref 中心の状態管理は Copy 可能な Signal APIに置き換えられ、イベントハンドラや future で繰り返し Clone する負担が軽減
  • 単一の dioxus::launchdx serve --platform の流れで Web、デスクトップ、Fullstack アプリを実行し、CLI が対象プラットフォームに合った ビルド feature を自動で渡す
  • アセットのホットリロード、イベントの再設計、デスクトップレンダリング改善、サーバー関数ストリーミングもあわせて変更され、単一の Rust コードベースの適用範囲が拡大

Dioxus 0.5のリリース方針

  • DioxusはRustでGUIを作るライブラリであり、Webアプリ・デスクトップアプリ・モバイルアプリの配布に使われている
  • 0.5リリースは、コミュニティが求めた 簡素化、堅牢性、完成度向上を目標に設計された
  • 主な変更点は以下の通り
    • dioxus-core の完全な書き直しと unsafe コードの排除
    • use_stateuse_ref の代わりに Signal ベースのAPIを導入
    • すべてのライフタイムと cx: Scope 状態を削除
    • すべてのプラットフォームでアプリを開始する単一の launch 関数
    • TailwindとVanilla CSSをサポートするアセットのホットリロード
    • ネイティブ WebSys イベント型へのアクセスを許可するイベントの再設計
    • Error Boundary、Server Future、Suspense の統合
    • デスクトップ reconciliation を5倍改善
    • サーバー関数ストリーミングとFullstackホットリロード
  • Dioxus 0.4から更新するユーザー向けに migration guide が提供されている

ライフタイムとScopeの削除

  • Dioxus 0.1から0.4までは、コンポーネント内部の値が 'bump ライフタイムを持ち、これによりイベントリスナーでhook、props、scopeを複製なしで使えた
  • イベントハンドラではおおむねうまく動作していたが、Dioxusのfutureは 'static である必要があり、値をfuture内へ移動する前に clone が必要だった
  • ライフタイムエラーが発生すると、hook自体ではなく cx'static より長く生存する必要がある、といったメッセージが出て混乱を招くことがあった
  • Dioxus 0.5は Scope'bump ライフタイムを削除し、Element をライフタイムのない形に変更
  • コンポーネントは今後、scopeパラメータなしでpropsを直接受け取れる
    • 例:fn MyComponent(name: String) -> Element
  • ランタイム関数はコンポーネント内部だけでなく、futureやイベントハンドラ内部でも直接使用できる
  • Element'static になったことで、hook内で使ったりcontext APIを通じて提供したりすることも可能に
  • この変更は、仮想リストやオフスクリーンレンダリングのようなAPIを実装しやすくする基盤になる

dioxus-core のunsafe排除

  • 'bump ライフタイムとscopeの削除は、Dioxus内部のunsafeコードを減らす機会を作った
  • dioxus-core 0.5 にはunsafeコードがない
  • 一部の依存関係には少量のunsafeが残っており、Dioxusチームは0.5リリースサイクル中にこれを取り除く計画
  • 残るunsafeは、単に削除可能なもの、またはFFIのために必要なものに分類される

Signalベースの状態管理

  • Dioxus 0.5は、コンポーネントの中核的な状態プリミティブとして Signal を導入
  • Signalは従来の use_stateuse_ref に比べて2つの利点を持つ
    • 常に Copy 可能
    • 手動購読が不要
  • Copy状態

    • Signal<T> は内部の T 値が Copy でなくても Copy
    • この動作は、unsafeなしで実装された generational-box crate によって可能になった
    • 必要であればSignalを Send+Sync にでき、スレッド間で移動できる
    • Copy状態、Send+Sync Signal、staticコンポーネントの組み合わせにより、状態をfuture、イベントハンドラ、スレッドなど必要な場所へ簡単に移動できる
    • メモリ使用方式は0.4とほぼ同じだが、明示的な Clone は不要
  • スマート購読

    • Signalは値が変わったとき、どのコンポーネントを再実行するかをより細かく判断する
    • コンポーネントがSignal値を読んだ場合にのみ、そのコンポーネントが再実行される
    • async処理やイベントハンドラで読んだ場合は、コンポーネント再実行の購読として扱われない
    • 親がボタンクリックでSignalを変更するが値を直接読まず、子だけが値を読む場合、子だけが再レンダリングされる
    • この構造により、別の状態管理crateだった Fermi が不要になった
    • Fermiはstaticをキーに使う use_state に似たAPIを提供していた
    • Dioxus 0.5では GlobalSignal をstaticに置き、通常のSignalのように使える
    • Signalはcontext APIとも動作し、別途 use_shared_state hookなしでコンポーネント間の状態共有が可能
    • use_futureuse_memo のようなhook内でSignalを読むと、そのSignalがhook依存関係に自動追加される

CSSとアセットのホットリロード

  • Dioxus 0.5は、アセットシステム刷新の一部としてアセットディレクトリ内のCSSファイルのホットリロードを実装
  • CSSファイルがRSX内に現れると、dx CLIがそのファイルを監視し、実行中のアプリへ更新を即座にストリーミングする
  • 対応対象はWeb、Desktop、Fullstackで、モバイル対応は今後のモバイル中心アップデートで提供予定
  • Tailwind watcherと併用すると Tailwind CSSホットリロード もサポートされる
  • VSCodeでは custom regex extension によりTailwind classのヒントも受けられる
  • 複数デバイスに変更を同時にストリーミングし、対象デバイス全体でホットリロードできる

イベントシステムの再設計

  • Dioxusはリリース以来、クロスプラットフォームイベントAPIを作るためにsynthetic eventシステムを使ってきた
  • Synthetic eventはプラットフォーム間のイベント動作とネットワークシリアライズに有用だが、限界もあった
  • Dioxus 0.5は各プラットフォームの 基盤イベント型 を公開し、クロスプラットフォームAPI向けのtraitもあわせて提供する
  • この変更の利点は2つ
    • プラットフォームイベント型から必要な情報を直接得たり、ほかのライブラリへ渡したりできる
    • アプリが使わないイベントコードをbundle splittingできる
  • hello worldの例でgzippedサイズが約 25%減少
  • 小さなbundleを作るコツは Dioxus optimization guide に含まれている

クロスプラットフォーム実行API

  • Dioxus 0.5は、アプリ実行のための新しい クロスプラットフォームAPI を導入
  • 別のrendererパッケージを取り込む代わりに、dioxus crateでfeatureを有効化し、preludeの launch 関数を呼べばよい
  • 1つのアプリから次のプラットフォームを対象に実行できる
    • Desktop:dx serve --platform desktop
    • SPA Web:dx serve --platform web
    • Fullstack:dx serve --platform fullstack
  • CLIは対象プラットフォームに応じて適切なビルドfeatureを自動的に渡す

アセットシステムβとManganis

  • DioxusとWebアプリでは、アセットパスが古くなりやすく、デスクトップとWebでリンクが異なる場合があり、bundleに含めるアセットを手動で追加しなければならない問題がある
  • アセットは性能上のボトルネックにもなり得る
  • Dioxus Mobileガイドの例では、0.4版は読み込みに7秒かかり、9MBのリソースを転送していた
  • 0.5のモバイルガイドは同じ画像を使いながらも1秒未満でロードされ、必要なリソースは1/3に減った
  • Dioxus 0.5は新しいアセットシステム manganis を導入
    • CLIと統合され、アプリアセットを確認、バンドル、最適化する
    • APIがまだ不安定なため、別crateとして配布される
    • mg! マクロでアセットを包むとCLIが自動検出する
    • 詳細は manganis docs にある
  • 0.5リリースが進む間に、manganisアセットにもホットリロードを追加する計画

デスクトップレンダリングを5倍改善

  • Dioxusはレンダリングdiffを高速化するために複数の最適化を使う
  • Templatesrsx! マクロの静的部分のdiffをスキップさせる
  • Dioxus Webでは sledgehammer により、RustからDOM変更を高速に適用する
  • Dioxus 0.5は同じ方式をネットワーク経由の変更適用にも使う
  • DesktopとLiveView rendererは変更内容をJSONではなく バイナリプロトコル で通信する
  • レンダリング負荷の高い作業で、新rendererはブラウザに変更を適用する時間が1/5に減り、レイテンシは1/2に減った
  • Dioxus 0.4でrendererが止まり続けていたベンチマークが、Dioxus 0.5では滑らかに動作する

コンポーネント作成の便利機能

  • Dioxus 0.5は特定のelementを拡張し、属性をelementへ展開する機能をサポート
    • 例:img elementの属性を拡張した ImgPlus コンポーネントで、widthheightsrc のような通常の img 属性をそのまま受け取れる
  • 属性とコンポーネントに値を渡す際、構造体初期化の省略構文を使える
    • class: class の代わりに class のように書ける
  • 省略属性は IntoAttribute を実装するすべての項目で動作し、Signalもこの恩恵を受ける
  • Signal属性はまだdiffingをスキップしないが、0.5リリースサイクル中に性能最適化として追加される予定
  • 複数行に分かれた属性はマージできる
    • 同じ class 属性に条件付きの値を追加すると、空白を区切りとしてマージされる
    • Tailwindのようにコンパイル時解析が必要で、かつランタイム動的処理も必要なライブラリに重要
    • この構文はTailwind compilerと統合され、tailwind-merge のようなライブラリのランタイムオーバーヘッドを取り除く

サーバー関数ストリーミングとFullstack

  • Dioxus 0.5はストリーミングデータをサポートする最新の server functions crate をサポート
  • サーバー関数はクライアントへデータをストリーミングしたり、クライアントからサーバーへデータをストリーミングしたりできる
  • ストリーミングサーバー関数は、出力型を定義し、サーバー関数から TextStream を返す方式で作れる
  • 時間のかかる作業中にクライアントを更新するのに適している
  • KalosmとローカルLLMを使い、一般的なハードウェアでOpenAI ChatGPT endpointに似た機能を提供する例がある
  • CLIは現在 fullstack プラットフォームをサポートし、クライアントとサーバーのホットリロードおよび並列ビルドを提供する
    • dx serve
    • dx serve --platform fullstack

LiveView、アセットハンドラ、ファイル処理

  • Dioxus 0.5ではrouterがLiveViewアプリでデフォルト動作する
  • Dioxus Desktopはcustom asset handlerをサポート
  • Custom asset handlerにより、RustコードからJavaScriptを経由せずブラウザへデータを効率的にストリーミングできる
  • 動画ストリーミングのような帯域幅の大きい通信に適している
  • gstreamerやwebrtcのデータを直接webviewへ渡せるため、フレームを直接エンコード・デコードする必要を減らせる
  • デスクトップのファイルドロップもイベントシステムへネイティブに統合される

エラー処理

  • DioxusはError Boundaryと throw traitにより、上位コンポーネントでエラーを簡単に処理できるようにする
  • throw 方式はエラー状態と早期returnの利点を組み合わせる
  • Debug を実装する Result 型で throw を呼んでエラー状態に変え、? で早期returnできる
  • ErrorBoundary コンポーネントは、子で投げられたエラーがあると別のコンポーネントをレンダリングする
  • ErrorBoundary はネスト可能で、アプリの複数レベルでエラーを捕捉できる
  • このパターンは、復旧不能なエラーが発生したときにpanicしたりエラーごとに状態を直接管理したりせず、グローバルなエラー状態を扱うのに有用

開発体験とテンプレート

  • Dioxusは0.3でホットリロードを導入し、0.4でDesktopに追加し、0.5ではデフォルトで有効化した
  • dx serve でアプリを実行すると、開発モードではデフォルトで ホットリロード が有効になる
  • Desktopアプリでホットリロードできず全体の再コンパイルが必要な場合でも、開いているウィンドウの状態を保持して復元する
    • アプリウィンドウのサイズと位置が維持される
    • 編集のたびにアプリが画面全体を塞ぐ状況を減らす
  • 新しいテンプレートは、Web、Desktop、Mobile、TUI、Fullstackアプリを1つのコマンドで作れるよう整理された
  • dx new のデフォルトアプリはcreate-react-appに近い形へ変更
    • assets、CSS、基本的なデプロイ設定を含む
    • dioxus-std、VSCode Extension、ドキュメント、チュートリアルなど有用なリソースへのリンクを含む

Dioxus Communityとエコシステム

  • Dioxus Communityは0.5リリースに向けて重要なエコシステムcrateを更新
  • icons、charts、Dioxus専用標準ライブラリのようなcrateが、0.5リリース時点ですぐ使えるよう準備された
  • Dioxus Community プロジェクトは、元のmaintainerが退いた後も重要なcrateを最新状態に保つための新しいGitHub組織
  • Dioxus向けライブラリを作る場合、Dioxus側はその保守を支援でき、事実上「Tier 2」サポートとして維持することを目指す

今後予定されている機能

  • 0.5以降の計画には次の項目が含まれる
    • アセットシステムの安定化とより深い統合
    • lazy componentとともに出力 .wasm を直接bundle splitting
    • Islandsとresumable interactivity、Signalシリアライズ
    • Server componentとLiveViewをFullstackへ統合
    • 強化されたDevtoolsとテストフレームワーク
    • Mobile全体の刷新
    • WebSocket、SSE、progressive formなどを含むFullstack刷新

ServoベースのDioxus-Blitzプレビュー

  • Dioxus-Blitzの「Blitz 2.0」ではServoを統合し、Firefoxを動かしているものと同じCSSエンジンでWGPUネイティブレンダリングを目指す
  • Taffy layout libraryを作ったNico Burnsが、この作業を推進するためにフルタイムで参加
  • デモでは google.com をGPU上で900 FPSでレンダリング
  • 現在の実装はまだ完全ではなく、google.com のレンダリングもやや不自然だが、利用可能な水準へ急速に近づいている
  • リポジトリは https://github.com/jkelleyrtp/stylo-dioxus で確認できる

貢献方法

  • Dioxusプロジェクトは次の貢献を求めている
    • ドキュメント翻訳
    • “Good First Issues”への挑戦
    • ドキュメント改善
    • CLIへの貢献
    • Discordコミュニティでの質問回答
  • Dioxusチームは2024年の残り期間におけるコミュニティの支援に感謝し、アプリ開発を変えるための協力を求めている

1件のコメント

 
GN⁺ 2024-03-29
Hacker Newsでの意見
  • 昨年 Dioxus で Mastodon クライアント Ebou を作りました。全体として良い体験でしたが、欠けているものも多かったです。
    作業を始めた時点ではバージョン 0.2 で、今回の 0.5 の変更により、当時感じていた複雑さはほぼなくなったように見えます。まだ自分では試していませんが、ライフタイム(lifetime)の排除と、何度も clone し続けなければならない負担の軽減で、ずっと快適になりそうです。
    • Dioxus をどうやって選んだのか気になります。
      デスクトップ、Web/wasm、モバイルなどにデプロイできる ネイティブなリアクティブ UI を目指す Rust フレームワークはかなり多く(https://github.com/flosse/rust-web-framework-comparison)、選び間違えると放置されたフレームワークを保守するか、つらい移行を強いられるのではないかと心配しています。
      Rust の HTTP サーバーフレームワークも同じように多かったものの、今は Axum、Actix、Rocket が先行しているように見え、コミュニティの流れは Axum に移っているようなので、Actix を選んだのは間違いだったのかとも思っています。Dioxus が勝ちそうな兆しはあるのか、大きなコミュニティや YC の支援、勢い以外に、今選んでもよいと言える指標があるのか気になります。
      Leptos と Yew も主要な競合なのか、Dioxus より優れている点・劣っている点は何なのかも知りたいです。会社としては Rust、Actix、Bevy にかなり投資しており、今後は Bevy と Dioxus のようなフレームワークを組み合わせて、ネイティブのデスクトップ/モバイルクライアントを作ろうとしています。
      それから Dioxus という名前が Pokémon の Deoxys に由来しているのかも気になります。ロゴはそんな雰囲気ですが、コードベースには Pokémon への参照がありません。
  • 「全体として良かったが、欠けているものが多かった」という意見には同意します。
    9か月ほど前に Dioxus で sshfs 用の GUI フロントエンドを作りましたが、開発者がまだ実装を終えていない機能の壁にぶつかるまでは、本当に素晴らしい GUI フレームワーク だという印象でした。
    異なるコンテキスト間での状態共有も時々つらいですが、言語や基盤技術に関係なく、これまで使ったすべての GUI フレームワークでそうでした。Dioxus 0.5 はこの点で大きな前進のように見えます。私のブログは HTML のかなりの部分を Dioxus でレンダリングしていますが、限界まで押し込むような用途ではないので、とてもよく動いています。
  • Dioxus には注目していますが、まだ試す機会はありませんでした。
    ただ、ライフタイム排除 の解決策には少し首をかしげています。generational-box は一種の貧者のガベージコレクタではないかと思うのですが、性能への影響がどうだったのか気になります。
    ついでに、[generational-box]([https://crates.io/crates/generational-box](<https://crates.io/crates/generational-box>;)) のリンクは壊れています。
    • 貧者のガベージコレクタであることは確かですが、メモリ意味論 は以前のバージョンとまったく同じです。
      use_hook がコンポーネントのライフタイムの間値を所有するので、コンポーネントが消えるとその値も drop されます。すべての signal は依然として use_hook を使っているため、ライフタイムも同じです。use_hook の外で GenerationalBox::new() を呼ぶことは通常推奨されないため、性能への影響はありません。
      ループ内で GenerationalBox::new() を乱用すると、そのゴミはコンポーネントが drop されるまで残りますが、ほとんどの場合は Map や Vec に push/pop するでしょうし、その場合は通常のメモリ意味論が適用されます。
    • これは本質的には 自動参照カウント です: https://en.wikipedia.org/wiki/Automatic_Reference_Counting
  • Rust プログラマーではありませんが、generational-box クレートがどう動くのか気になります。
    一種の アリーナアロケーション だということは分かりますが、「コピーなしのコピー」をどうサポートしているのか、また内部的に世代付きの RefCell アリーナを作り、GenerationalBoxCopy だという説明がなぜ安全なのか理解できません。
    静的データへのポインタを作れることは分かりますが、静的ライフタイムを持たない値の場合はどうなるのか気になります。
    • データをコピーしているのではなく、データへの参照 をコピーしているのです。
      データ参照はプログラムの存続期間中維持されます。generational box はプログラムの存続期間より短く生きるデータを入れられるようにしますが、そのデータは参照を含んではいけません。入れたデータを drop すると、その box は別の割り当てに再利用されます。
      中央集約型のアリーナではなく box を使う点を除けば、世代別アリーナと非常によく似たアプローチで、ロックの問題を避けるための選択です。drop された後に Copy 参照でデータへアクセスしようとすると、分かりやすいエラーメッセージとともに失敗します。
    • このクレートについてはよく知りませんが、Rust 的に見ると、Copy には特定の意味があります。
      ある型が Copy トレイトを実装しているということは、memcpy でコピーできるという意味で、ディープコピーではなく シャローコピー に近いものです。
      なので「コピーなしのコピー」ではなく、Copy でない型を Copy 型のように扱えるようにするものだと理解しています。README には静的コンテンツが必要だと書かれているので、静的ライフタイムを持たない値については「そうはできない」が答えです。
  • しばらく見守ってきたので、リリースされてとてもうれしいです。
    Dioxus は React が成功した要素を多く取り入れつつ、その上で素早く革新し、配布しているところが良いです。今回のリリースの signals を試すのが楽しみです。
  • RSX ではなく、React/JSX より SwiftUI に近い何かであってほしかったです。
    React が JS と Web にもたらした良いことや、その知名度は認めますが、2024 年に言語や DSL をゼロから設計できるなら、「リアクティブ UI」のコードが必ず React のように見えなければならないとは思いません。
    SwiftUI が完璧だという意味ではありませんが、SwiftUI で書くコードは、React で似たようなコードを書くときよりも、はるかにすっきり整理され、区切られているように感じます。

クロスプラットフォームGUIでJSXを使う本当の利点は、Web向けの既存ライブラリを再利用できることくらいですが、RSXは開発者がJSXの概念知識をRSXへ移せるという点以外には、「移植可能な価値」が小さく見えます。むしろReact/JSXパラダイムより客観的に優れていると思える新しいパラダイムを学ぶほうが、よい妥協案です
要するに「SwiftUIだがクロスプラットフォーム」なプロジェクトがあるとよいのですが、まだありません。@Tokamak/TokamakUIは知っていますが、まだかなり未完成で活動も減っているようです

  • https://ribir.org/があります
    現在はLinux/mac/windowsのネイティブデスクトップアプリのみ対応していますが、WASM、Web、モバイル対応の計画があります
  • Freenetの分散型ホームページを作るためにDioxusを選びました
    Freenetを設定した人たちが最初に目にする分散型Webサイトになる予定です。数年にわたって断続的に作業してきたKotlinのWebフレームワークKwebとも少し似ていて、特に状態処理と、コードからHTMLへマッピングされるDSL方式が似ています。今のところ気に入っています
    https://freenet.org/
    https://kweb.io/
    • すばらしい。最初にDSLを設計したときにkwebを見た気がしますし、両者は本当に似ています
      実はKotlinのファンで、Kotlin DSLと並行性モデルが好きです
  • Tauriと比べてどうなのか気になります
    • READMEにその内容を書いてあります: https://github.com/dioxusLabs/dioxus/?tab=readme-ov-file#dioxus-vs-tauri
      TauriはフロントエンドをWebViewに入れ、ネイティブRust関数とはElectronのようにIPC境界を通じて通信する必要があります
      DioxusではRustコードがネイティブ側にあるため、ファイルシステムの読み取りやWebSocketのような処理にIPCは不要です。TauriはフロントエンドをWASMにコンパイルすることを強制し、興味深いRustクレートの中にはwasmにコンパイルできないものも多くあります
      IPC境界がないと開発がどれほど単純になるかは、言葉では言い表しにくいです。DioxusのツールはRustだけを対象にしているので、ゼロからバンドル済みの.appまで1分以内で到達できます。新規ビルドは約12秒、新規バンドルは約20秒です
      それでもTauriがもたらす柔軟性、つまりWeb互換UIなら何でもフロントエンドとして使える点は大いに気に入っており、Tauriアプリ内でDioxusを使うこともできます
    • 私もこの質問をしようと思って来ました
      DioxusがREADMEで直接扱っているのはよかったですが、両方を使った人たちの実体験も気になります
      Tauriでおもちゃのデスクトップアプリを作ってみたところ、Webフロントエンドがキー入力ごとに更新して処理しても遅延がないほどIPCが速いかは確認でき、答えは「はい」でした。大きなファイルをキー入力ごとにフロントエンドからRust層へ送り、またフロントエンドへ戻せるかは、少なくとも私の素朴な実装では「いいえ」でした
      TauriとDioxusのどちらにもよい事例は多く、あるケースではDioxusのほうがよさそうです。「私たちのプロジェクトではXとYのためにDioxusまたはTauriを選んだ」といった比較経験談を聞きたいです。Dioxusは本当にすばらしく見えるので、使ってみるのが楽しみです
  • ネイティブアプリはどのようにレンダリングするのか気になります。やはり何らかのブラウザインスタンス内で動くのでしょうか?
    • レンダラーとしてシステムのWebViewを使うか、styloを取り込んだ実験的なWGPUベースのエンジンを選べます
      styloはServoのうちFirefoxと共有されている部分です。長期的には人々をWGPUレンダラーへ移行させたいですが、まだかなり初期段階であり、Dioxusを使う多くの企業は、WebViewがアプリの90%程度には十分よい解決策だと現実的に理解しています
  • 「0.5リリースサイクルの間に、いくつかの依存関係に残っているごく小さなunsafeを取り除く予定」という部分について、その用途が何で、動機が何なのか見てみたいです
    人々がときどきunsafeを安易に使いすぎるのは理解しますが、標準ライブラリもunsafeだらけで、そこで線を引くのは時々、砂上に線を引くように見えます
    • ほとんどはFFIとやり取りしたり、一部の型をSend/Syncとして宣言したりするために必要です
      3か所で使っています。iOSの一部FFI修正、signalに関数呼び出し構文を可能にする実装、ポインタをハッシュとして使うIDにSend/Syncを実装する部分です
      最後のものは、今見るとusizeに置き換えれば取り除けるかもしれません
    • 人々がunsafeを少し過度に恐れることがある、という点には同意します
      それでもクレート作者が自分のクレートからunsafeを取り除くことを目標にするのが、必ずしも悪い判断というわけではありません
      すべてのunsafeを取り除こうとするクレート作者は、ユーザーが負うべき信頼の負担を減らそうとしている場合が多いです。これこそがunsafeキーワードの力だと思います。実際にはtrust_meブロックとcheck_yourself関数に分かれているべきだったのかもしれません
      unsafeはメモリ安全性に関する議論を、コード内の非常に狭く監査可能な場所に限定し、同時に信頼についての新しく管理可能な議論を生み出します
  • ReactがフックAPIにuse*という命名規則を作った理由は理解していますが、Dioxusで新しいsignalを作る関数がなぜuse_signalなのか気になります
    let mut count = use_signal(|| 0);は新しいsignalを作る呼び出しではないのですか? signalはレンダリングごとに作り直されず、それこそがsignalの核心です
    SolidJSではconst [count, setCount] = createSignal(0)のようにcreateSignalでsignalを作り、このほうがはるかに理解しやすいです
    API名は重要です。状態フックは異なる動作をし、useMemoのような補完要求も生じ得るためです。DioxusがReactに近く見せようとしていること以外に、use_signalという名前を選んだ理由があるのか気になります
    • Dioxusは今でもコンポーネントを再レンダリングしますが、コンポーネントが生成するrsxに多くの最適化を適用して、Solidに近い性能を出しています
      SolidよりはPreactに近いです
      最適化には、UIの動的な断片を別の「diff bin」に分離すること、基本的なメモ化、signalが属性を暗黙的にdirty/managedとしてマークすることが含まれます