Skip to content

Commit 9e122ee

Browse files
committed
Batch workspace metadata updates on initial load
When subscribing to metadata, backend sends one event per workspace synchronously. This was causing N re-renders for N workspaces. Now we batch these updates using queueMicrotask - all synchronous events are collected and flushed in a single state update after the current task completes. This reduces 19 re-renders to 1 on startup.
1 parent 5743f4b commit 9e122ee

File tree

1 file changed

+27
-5
lines changed

1 file changed

+27
-5
lines changed

src/hooks/useWorkspaceManagement.ts

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,34 @@ export function useWorkspaceManagement({
4141
// Subscribe to workspace metadata updates
4242
// NOTE: onMetadata sends all current metadata immediately upon subscription,
4343
// then sends updates as they happen (e.g., from renames)
44+
45+
// Batch updates to avoid triggering re-renders for each workspace on initial load
46+
let pendingUpdates = new Map<string, FrontendWorkspaceMetadata>();
47+
let batchScheduled = false;
48+
49+
const flushBatch = () => {
50+
if (pendingUpdates.size > 0) {
51+
const updates = pendingUpdates;
52+
pendingUpdates = new Map();
53+
batchScheduled = false;
54+
55+
setWorkspaceMetadata((prev) => {
56+
const updated = new Map(prev);
57+
for (const [id, metadata] of updates) {
58+
updated.set(id, metadata);
59+
}
60+
return updated;
61+
});
62+
}
63+
};
64+
4465
const unsubscribe = window.api.workspace.onMetadata((event: { workspaceId: string; metadata: FrontendWorkspaceMetadata }) => {
45-
setWorkspaceMetadata((prev) => {
46-
const updated = new Map(prev);
47-
updated.set(event.workspaceId, event.metadata);
48-
return updated;
49-
});
66+
pendingUpdates.set(event.workspaceId, event.metadata);
67+
68+
if (!batchScheduled) {
69+
batchScheduled = true;
70+
queueMicrotask(flushBatch);
71+
}
5072
});
5173

5274
return () => {

0 commit comments

Comments
 (0)