制作ノートへ
Production DeskのElectron版とRust版におけるコンテキスト切り替えを、ソースコードから比較した図。

Production DeskをElectronに​戻す理由

2026年10月24日

ボトルネックは​言語ではなく、​操作の​たびに​走る​処理の​量でした。

エンジニアリング制作アニメーション

Rust移植は、Electronより軽く、操作も速くなるはずだと思っていました。でも、ショットやアクトを切り替えるたびに画面が跳ね、小さな読み込み表示が繰り返される。制作の手が止まるほど遅いなら、言語の理論値に意味はありません。私は制作に使う版をElectronへ戻します。

これは「Rustでは速いUIを作れない」という結論ではありません。今回のソースを追うと、差を生んでいるのは言語よりも、コンテキスト切り替えで何を読み直し、何を複製し、いつ画面へ渡すかという構成でした。

A / 二つの経路

同じクリックが、同じ仕事をしていなかった

Electron版では、選択済みのプロジェクト全体をReactのworkspaceが保持しています。ノードを選ぶ処理は、未保存データのflushを待ってから選択IDを更新し、必要な祖先をツリーで展開します。画面はその常駐プロジェクト状態から描画されます。

Rust版では、SelectNodeを受けたhostが画面をbusyにしてからsession workerへ送ります。workerは`prepare_context_switch`で保存ストアを読み直し、プロジェクトのrevisionとcontextを検証して候補sessionを作ります。`session_payload`はそのsnapshot全体をcloneし、各ボードで選択中のメディアバイト列も別々のVecへコピーします。hostは受け取った後、BoardsやReview、Generation、Timelineの関連状態を無効化し、ボード一覧を作り直します。同一画像を安全に再利用できない場合は画像をdecodeして、egui側へ新しいRGBAフレームを渡し、GPU textureとして登録します。Timelineではさらにコンポジションを準備し、ネイティブ再生を開いてプレビューを出します。revision確認や変更中データの保護には意味がありますが、この移植ではその仕事がショット切り替えのたびに操作経路へ入りました。

Electronは常駐するプロジェクト状態から選択を更新し、Rustはセッションスナップショット、選択中メディア、ネイティブプレビューを順に準備する比較図。
ソースコードから見た構成比較。各ボックスの時間を同一条件で測定したベンチマークではありません。
別のショットを選択した後にElectronとRustで通る処理を並べた図。
遅延の内訳を分離した数値はまだありません。ここで示すのは、実装上の処理経路です。

C / 画面記録

切り替え中に見えていた状態

どちらも同じ5RPSプロジェクトの画面記録ですが、開始時のボード数と操作列は一致していません。Rustの記録ではTimelineへ移る途中、プレビュー欄が「Composition preview unavailable」となり、「Please wait for the current operation.」という待機表示も出ます。その後に絵が現れます。Electronの記録ではTimelineへ移った時点でコンポジション画像が表示されています。これはこの二つの録画で見える差であり、同じ条件の速度計測ではありません。

Electron版の画面記録

10.27秒。15ページのボードから始まり、BoardsとTimelineを移動します。

Rust版の画面記録

18.93秒。22ページのボードから始まり、Timelineではプレビュー待ち表示が見えます。

元動画は4Kの画面収録で、公開用コピーはアスペクト比を保った1920×1204、48fpsのH.264/AACへ変換しました。元ファイルはそのまま保管しています。

B / コミットに残った経緯

読み込みを隠す修正が続いた

移植中のコミットメッセージにも、画面の引き継ぎを直し続けた経緯が残っています。たとえば `c065c575` は「Fix Rust context navigation stalls and loading layout shifts」、`360f9179` は「Keep context navigation steady and enable live timeline scrubbing」、`0b40fe26` は「Keep every context page steady while its replacement loads」、`57a5fc2c` は「Keep timeline context steady until preview is ready」です。読み込み中に古い表示を保つことは画面の跳ねを和らげますが、次のコンテキストを準備する総仕事量そのものは減らしません。

`f25daf73`の「defer unused rasters」も、読まなくてよい画像を後回しにする局所的な改善でした。こうした修正は必要でしたが、選択操作がElectronより軽くなったことの証明にはなりません。

ここで比較できるのはソース上の経路と、私が繰り返し報告した使用感です。録画を同じプロジェクト、同じメディア、同じ操作列でフレーム計測した数値はありません。従って、特定の割合や「Rustは何倍遅い」という主張はしません。

D / 判断と次の条件

Rustを捨てるのではなく、この移植を止める

RustはCPU処理、メモリ管理、ネイティブ統合で強い選択肢です。ただし、UIの応答性は言語だけでは決まりません。I/O待ち、画像のdecode、不要なclone、同期準備、描画のinvalidations、ローディング状態の切り替えが操作経路に入れば、Rustでも遅く、ぎくしゃくします。Electronは魔法のように速いのではなく、現在の実装ではすでに開いているプロジェクト内で選択だけを変えられる。今回の用途では、その設計差が重要でした。

制作を続けるため、私はElectron版を使います。タイムラインのルーラーscrubではpointer位置をanimation frameごとにまとめ、release時に最後の位置を必ず反映する変更を用意しました。この更新を入れたアプリを、ここから手元でQAします。これはショット切り替え時の重さや画面の跳ねまで直したという意味ではありません。

Rust版を再検討するなら、言語の比較を繰り返すのではなく、ショット切り替え時のsnapshot再利用、可視範囲だけの画像読み込み、共有media/texture cache、Timeline準備の非同期化を先に設計し、Electronと同一条件で測る必要があります。今回はその再設計より、使える道具へ戻ることを選びます。

ソース参照:Electronのworkspace選択処理、Rustのsession payload、Rust Timeline再生準備。