Skip to content

Commit 601747d

Browse files
committed
Batch logs per frame render
1 parent f93eb37 commit 601747d

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

packages/tasks/src/hooks/useWorkspaceLogs.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,34 @@ import { useEffect, useState } from "react";
22

33
import { useTasksApi } from "./useTasksApi";
44

5+
/**
6+
* Subscribes to workspace log lines pushed from the extension.
7+
* Batches updates per animation frame to avoid excessive re-renders
8+
* when many lines arrive in quick succession.
9+
*/
510
export function useWorkspaceLogs(): string[] {
611
const { onWorkspaceLogsAppend, closeWorkspaceLogs } = useTasksApi();
712
const [lines, setLines] = useState<string[]>([]);
813

914
useEffect(() => {
15+
let pending: string[] = [];
16+
let frame = 0;
17+
1018
const unsubscribe = onWorkspaceLogsAppend((newLines) => {
11-
setLines((prev) => [...prev, ...newLines]);
19+
pending.push(...newLines);
20+
if (frame === 0) {
21+
frame = requestAnimationFrame(() => {
22+
const batch = pending;
23+
pending = [];
24+
frame = 0;
25+
setLines((prev) => prev.concat(batch));
26+
});
27+
}
1228
});
29+
1330
return () => {
1431
unsubscribe();
32+
cancelAnimationFrame(frame);
1533
closeWorkspaceLogs();
1634
};
1735
}, [closeWorkspaceLogs, onWorkspaceLogsAppend]);

test/webview/tasks/useWorkspaceLogs.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { act, renderHook } from "@testing-library/react";
2-
import { describe, expect, it, vi } from "vitest";
2+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
33

44
import { TasksApi } from "@repo/shared";
55
import { useWorkspaceLogs } from "@repo/tasks/hooks/useWorkspaceLogs";
@@ -33,6 +33,8 @@ function renderLogs() {
3333
},
3434
}),
3535
);
36+
// Flush the requestAnimationFrame batch used by useWorkspaceLogs.
37+
vi.runAllTimers();
3638
});
3739
},
3840
unmount() {
@@ -43,6 +45,9 @@ function renderLogs() {
4345
}
4446

4547
describe("useWorkspaceLogs", () => {
48+
beforeEach(() => vi.useFakeTimers());
49+
afterEach(() => vi.useRealTimers());
50+
4651
it("returns empty array initially", () => {
4752
const h = renderLogs();
4853
expect(h.lines).toEqual([]);

0 commit comments

Comments
 (0)