refactor(react/svelte): use node lookup for perf improvement

This commit is contained in:
moklick
2023-11-13 16:43:57 +01:00
parent 6e1e702cf3
commit a147a20f6e
22 changed files with 127 additions and 78 deletions
+3 -3
View File
@@ -33,7 +33,7 @@ export type GroupedEdges<EdgeType extends EdgeBase> = {
export function groupEdgesByZLevel<EdgeType extends EdgeBase>(
edges: EdgeType[],
nodes: NodeBase[],
nodesLookup: Map<string, NodeBase>,
elevateEdgesOnSelect = false
): GroupedEdges<EdgeType>[] {
let maxLevel = -1;
@@ -43,8 +43,8 @@ export function groupEdgesByZLevel<EdgeType extends EdgeBase>(
let z = hasZIndex ? edge.zIndex! : 0;
if (elevateEdgesOnSelect) {
const targetNode = nodes.find((n) => n.id === edge.target);
const sourceNode = nodes.find((n) => n.id === edge.source);
const targetNode = nodesLookup.get(edge.target);
const sourceNode = nodesLookup.get(edge.source);
const edgeOrConnectedNodeSelected = edge.selected || targetNode?.selected || sourceNode?.selected;
const selectedZIndex = Math.max(
sourceNode?.[internalsSymbol]?.z || 0,
+21 -9
View File
@@ -18,19 +18,21 @@ type ParentNodes = Record<string, boolean>;
export function updateAbsolutePositions<NodeType extends NodeBase>(
nodes: NodeType[],
nodesLookup: Map<string, NodeType>,
nodeOrigin: NodeOrigin = [0, 0],
parentNodes?: ParentNodes
) {
return nodes.map((node) => {
if (node.parentNode && !nodes.find((n) => n.id === node.parentNode)) {
if (node.parentNode && !nodesLookup.has(node.parentNode)) {
throw new Error(`Parent node ${node.parentNode} not found`);
}
if (node.parentNode || parentNodes?.[node.id]) {
const parentNode = node.parentNode ? nodes.find((n) => n.id === node.parentNode) : null;
const parentNode = node.parentNode ? nodesLookup.get(node.parentNode) : null;
const { x, y, z } = calculateXYZPosition(
node,
nodes,
nodesLookup,
{
...node.position,
z: node[internalsSymbol]?.z ?? 0,
@@ -62,7 +64,7 @@ type UpdateNodesOptions<NodeType extends NodeBase> = {
export function updateNodes<NodeType extends NodeBase>(
nodes: NodeType[],
storeNodes: NodeType[],
nodesLookup: Map<string, NodeType>,
options: UpdateNodesOptions<NodeType> = {
nodeOrigin: [0, 0] as NodeOrigin,
elevateNodesOnSelect: true,
@@ -73,7 +75,7 @@ export function updateNodes<NodeType extends NodeBase>(
const selectedNodeZ: number = options?.elevateNodesOnSelect ? 1000 : 0;
const nextNodes = nodes.map((n) => {
const currentStoreNode = storeNodes.find((storeNode) => n.id === storeNode.id);
const currentStoreNode = nodesLookup.get(n.id);
const node: NodeType = {
...options.defaults,
...n,
@@ -96,10 +98,12 @@ export function updateNodes<NodeType extends NodeBase>(
},
});
nodesLookup.set(node.id, node);
return node;
});
const nodesWithPositions = updateAbsolutePositions(nextNodes, options.nodeOrigin, parentNodes);
const nodesWithPositions = updateAbsolutePositions(nextNodes, nodesLookup, options.nodeOrigin, parentNodes);
return nodesWithPositions;
}
@@ -107,6 +111,7 @@ export function updateNodes<NodeType extends NodeBase>(
function calculateXYZPosition<NodeType extends NodeBase>(
node: NodeType,
nodes: NodeType[],
nodesLookup: Map<string, NodeType>,
result: XYZPosition,
nodeOrigin: NodeOrigin
): XYZPosition {
@@ -114,12 +119,13 @@ function calculateXYZPosition<NodeType extends NodeBase>(
return result;
}
const parentNode = nodes.find((n) => n.id === node.parentNode)!;
const parentNode = nodesLookup.get(node.parentNode)!;
const parentNodePosition = getNodePositionWithOrigin(parentNode, parentNode?.origin || nodeOrigin);
return calculateXYZPosition(
parentNode,
nodes,
nodesLookup,
{
x: (result.x ?? 0) + parentNodePosition.x,
y: (result.y ?? 0) + parentNodePosition.y,
@@ -130,8 +136,9 @@ function calculateXYZPosition<NodeType extends NodeBase>(
}
export function updateNodeDimensions(
updates: NodeDimensionUpdate[],
updates: Map<string, NodeDimensionUpdate>,
nodes: NodeBase[],
nodesLookup: Map<string, NodeBase>,
domNode: HTMLElement | null,
nodeOrigin?: NodeOrigin,
onUpdate?: (id: string, dimensions: Dimensions) => void
@@ -146,7 +153,8 @@ export function updateNodeDimensions(
const { m22: zoom } = new window.DOMMatrixReadOnly(style.transform);
const nextNodes = nodes.map((node) => {
const update = updates.find((u) => u.id === node.id);
const update = updates.get(node.id);
if (update) {
const dimensions = getDimensions(update.nodeElement);
const doUpdate = !!(
@@ -158,7 +166,7 @@ export function updateNodeDimensions(
if (doUpdate) {
onUpdate?.(node.id, dimensions);
return {
const newNode = {
...node,
...dimensions,
[internalsSymbol]: {
@@ -169,6 +177,10 @@ export function updateNodeDimensions(
},
},
};
nodesLookup.set(node.id, newNode);
return newNode;
}
}