بازنویسی Conductor؛ چطور دو برابر سریع شد
خلاصهٔ کاملتر
Conductor یه اپ دسکتاپ برای کار با ایجنتهای کدنویسیه که معماریش local-first هست: یه اپ React داخل پوستهی Tauri، و SQLite بهعنوان منبع حقیقت برای workspaceها، تاریخچهی چت و تنظیمات. چون چیزی روی سرور راه دور نیست، UI هیچوقت منتظر شبکه نمیمونه. تیم میگه همین انتخاب از روز اول سریعشون کرده بود، ولی بازم چت و worktree و نمایش کد کند بودن.
نکتهی کلیدی اینه که گلوگاه از بین نمیره، فقط جابهجا میشه. وقتی شبکه رو حذف کنی، تازه هر رندر اضافی و هر اسکرول کند میشه کندترین چیزی که کاربر حس میکنه. برای همین قبل از هر بهینهسازی باید میفهمیدن دقیقاً وقت کجا تلف میشه؛ و این با Tauri سخت بود.
ماجرا اینه که Electron یه نسخه از Chromium رو با خودش میاره، پس کل ابزار Chrome از جمله افزونهی React DevTools رو مجانی داری. ولی Tauri مرورگر بستهبندی نمیکنه و UI رو توی وبویوی سیستمعامل (روی مک همون WKWebView سافاری) رندر میکنه. همین بسته رو سبک و کولداستارت رو سریع نگه میداره، ولی تنها پروفایلرت میشه Web Inspector سافاری که فقط JavaScript رو پروفایل میکنه، نه React رو. افزونهی React DevTools هم اصلاً داخل WKWebView بالا نمیاد.
ترفندشون این بود: فرانتاند Conductor یه اپ تکصفحهای Viteه و فقط جایی به پوستهی نیتیو احتیاج داره که از طریق پل invoke() با هستهی Rust حرف میزنه. پس همون یه نقطه رو شیم کردن تا عین همون کلاینت توی Chrome اجرا شه و پروفایلر Chrome و React DevTools واقعی روش کار کنه:
export function invoke<T>(cmd: string, args?: Record<string, unknown>): Promise<T> {
if ("__TAURI_INTERNALS__" in window) return tauriInvoke<T>(cmd, args);
return fetch(`/__backend__/${cmd}`, {
method: "POST",
body: JSON.stringify(args ?? {}),
}).then((r) => r.json());
}با پروفایلر واقعی، گلوگاه دیگه حدس نبود: مشکل خود React بود که خیلی بیشتر از نیاز دوباره رندر میکرد. چون چند view (سایدبار، nav، چت، ترمینال، ادیتور) همزمان mount هستن و React Router موقع هر ناوبری رفرنسهای تازهای از params و search میسازه، هر کامپوننتی که اونا رو میخوند دوباره رندر میشد، حتی وقتی واقعاً چیزی عوض نشده بود. این رندرها هم آبشاری کل اپ رو درگیر میکردن.
نکات کلیدی:
- معماری local-first با SQLite، شبکه رو از معادلهی سرعت حذف میکنه
- وقتی یه گلوگاه بره، گلوگاه بعدی (اینجا رندر اضافی React) برجسته میشه
- Tauri سبکه ولی React DevTools داخل WKWebViewش کار نمیکنه
- با شیم کردن پل invoke() همون کلاینت توی Chrome اجرا شد و پروفایلر واقعی بهدست اومد
- رفرنسهای تازهی params در React Router باعث رندرهای آبشاری بیدلیل میشدن




