Skip to content
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,7 @@
## 2024-05-24 - [React Component Memoization]
**Learning:** In React components like `WorkspaceHome`, when layout state or polling changes trigger parent re-renders, expensive child components like `EmailDetail` will also re-render unnecessarily if not memoized.
**Action:** Always consider `React.memo` for heavy child components that rely on stable props (like IDs) when the parent component has frequent unrelated state updates.
## 2025-02-12 - Replaced O(N) Array.from().slice() with O(1) loop in NetworkGraph

**Learning:** When extracting a small slice of items from a large Map or Set in React render loops or useMemo, avoiding `Array.from(iterable).slice(0, N)` prevents a full O(N) intermediate array allocation.
**Action:** Use a bounded `for...of` loop with an early `break` to maintain O(1) performance instead of converting the entire iterable to an array first.
37 changes: 27 additions & 10 deletions frontend/src/components/NetworkGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -286,19 +286,36 @@ export default function NetworkGraph() {

const firstEdge = edges[0] ?? null;
const relationshipOptions = useMemo(() => {
return Array.from(edgeMap.values()).slice(0, 5).map((edge, index) => ({
edge,
id: String(edge.id),
label: `관계 ${index + 1}: ${describeEdge(edge, nodeMap)}`,
}));
// ⚡ Bolt: Replace O(N) Array.from().slice() with O(1) bounded for-of loop
// to avoid full intermediate array allocation when extracting only a few items
const options = [];
let index = 0;
for (const edge of edgeMap.values()) {
if (index >= 5) break;
options.push({
edge,
id: String(edge.id),
label: `관계 ${index + 1}: ${describeEdge(edge, nodeMap)}`,
});
index++;
}
return options;
}, [edgeMap, nodeMap]);

const nodeOptions = useMemo(() => {
return Array.from(nodeInstanceMap.values()).slice(0, 8).map((node) => ({
id: String(node.id),
label: `노드: ${String(node.label ?? node.id)}`,
node,
}));
// ⚡ Bolt: Replace O(N) Array.from().slice() with O(1) bounded for-of loop
const options = [];
let index = 0;
for (const node of nodeInstanceMap.values()) {
if (index >= 8) break;
Comment thread
seonghobae marked this conversation as resolved.
options.push({
id: String(node.id),
label: `노드: ${String(node.label ?? node.id)}`,
node,
});
index++;
}
return options;
}, [nodeInstanceMap]);

const selectRelationship = (edge: Edge, status: string) => {
Expand Down
33 changes: 0 additions & 33 deletions test_parse3.py

This file was deleted.

Loading