Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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;
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