Skip to content

Commit 1d4e999

Browse files
committed
feat: optimize network graph performance with memoization and aggregation
1 parent f9a0413 commit 1d4e999

6 files changed

Lines changed: 276 additions & 152 deletions

File tree

components/network-graph/network-graph-2d.tsx

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Link, Nodes } from "@utils/render_graph";
2-
import { useCallback, useEffect, useRef, useState } from "react";
2+
import React, { useCallback, useEffect, useRef, useState } from "react";
33
import {
44
createLinkLabel,
55
createNodeLabel,
@@ -12,13 +12,40 @@ import {
1212
useGraphForces,
1313
} from "./use-graph-data";
1414

15-
export const NetworkGraph2d = ({
15+
// Custom comparison to prevent unnecessary re-renders
16+
const arePropsEqual = (
17+
prevProps: GraphComponentProps,
18+
nextProps: GraphComponentProps
19+
): boolean => {
20+
// Compare data lengths (cheap check for data changes)
21+
if (
22+
prevProps.graphData.nodes.length !== nextProps.graphData.nodes.length ||
23+
prevProps.graphData.links.length !== nextProps.graphData.links.length
24+
) {
25+
return false;
26+
}
27+
// Compare physics values
28+
if (
29+
prevProps.chargeStrength !== nextProps.chargeStrength ||
30+
prevProps.linkDistance !== nextProps.linkDistance ||
31+
prevProps.centerGravity !== nextProps.centerGravity
32+
) {
33+
return false;
34+
}
35+
// Compare animate flag
36+
if (prevProps.animate !== nextProps.animate) {
37+
return false;
38+
}
39+
return true;
40+
};
41+
42+
export const NetworkGraph2d = React.memo(function NetworkGraph2d({
1643
graphData: inputData,
1744
chargeStrength = DEFAULT_PHYSICS.chargeStrength,
1845
linkDistance = DEFAULT_PHYSICS.linkDistance,
1946
centerGravity = DEFAULT_PHYSICS.centerGravity,
2047
animate = true,
21-
}: GraphComponentProps) => {
48+
}: GraphComponentProps) {
2249
const [ForceGraph2D, setForceGraph2D] = useState<any>(null);
2350
const graphRef = useRef<any>(null);
2451

@@ -119,11 +146,15 @@ export const NetworkGraph2d = ({
119146
ctx.stroke();
120147
}
121148

149+
// Base width scales with txCount (aggregated links are thicker)
150+
const txCount = link.txCount || 1;
151+
const baseWidth = 0.3 + Math.log10(txCount + 1) * 0.8;
152+
122153
ctx.beginPath();
123154
ctx.moveTo(source.x, source.y);
124155
ctx.lineTo(target.x, target.y);
125156
ctx.strokeStyle = link.color || "#999";
126-
ctx.lineWidth = 0.5;
157+
ctx.lineWidth = baseWidth;
127158
ctx.stroke();
128159
},
129160
[getPulseIntensity, pulsingLinks]
@@ -151,7 +182,7 @@ export const NetworkGraph2d = ({
151182
nodeId="id"
152183
enableNodeDrag={false}
153184
nodeLabel={(d: Nodes[0]) => createNodeLabel(d.id)}
154-
linkLabel={(d: Link) => createLinkLabel(d?.token_symbol, d?.token_name)}
185+
linkLabel={(d: Link) => createLinkLabel(d?.token_symbol, d?.token_name, d?.txCount)}
155186
nodeAutoColorBy={(n: Nodes[0]) => Object.keys(n.usedVouchers)[0]}
156187
backgroundColor={GRAPH_CONFIG.backgroundColor}
157188
graphData={displayedData}
@@ -165,4 +196,4 @@ export const NetworkGraph2d = ({
165196
d3VelocityDecay={GRAPH_CONFIG.d3VelocityDecay}
166197
/>
167198
);
168-
};
199+
}, arePropsEqual);

0 commit comments

Comments
 (0)