[client] Debug: create GUI windows on demand and destroy them on close

Experiment on top of the memory profiler: the main and Settings windows are no
longer created at startup or kept alive hidden, so an idle tray holds no webview
process. The WindowManager owns creation, rebuilds the main window on the next
show, and defers every show until the frontend reports it has rendered, which
keeps an empty webview off screen.

Measured on macOS: idle footprint drops from ~160 MB to ~74 MB, at the cost of
~150-250 ms per window open.
This commit is contained in:
Zoltan Papp
2026-08-07 14:43:52 +02:00
parent 04ca92d42b
commit bc73e6bd71
7 changed files with 296 additions and 74 deletions
@@ -0,0 +1,18 @@
import { useEffect, useRef } from "react";
import { Events } from "@wailsio/runtime";
import { useStatus } from "@/contexts/StatusContext.tsx";
const EVENT_WINDOW_PAINTED = "netbird:window-painted";
export const ReadySignal = () => {
const { isReady } = useStatus();
const sent = useRef(false);
useEffect(() => {
if (!isReady || sent.current) return;
sent.current = true;
void Events.Emit(EVENT_WINDOW_PAINTED);
}, [isReady]);
return null;
};
@@ -5,6 +5,7 @@ import { DebugBundleProvider } from "@/contexts/DebugBundleContext.tsx";
import { ProfileProvider } from "@/contexts/ProfileContext.tsx";
import { DialogProvider } from "@/contexts/DialogContext.tsx";
import { RestrictionsProvider } from "@/contexts/RestrictionsContext.tsx";
import { ReadySignal } from "@/components/ReadySignal.tsx";
export const AppLayout = () => {
return (
@@ -16,6 +17,7 @@ export const AppLayout = () => {
<DebugBundleProvider>
<ClientVersionProvider>
<Outlet />
<ReadySignal />
</ClientVersionProvider>
</DebugBundleProvider>
</RestrictionsProvider>