refactor(react/svelte): use node lookup for perf improvement
This commit is contained in:
@@ -30,6 +30,7 @@ export default function drag(domNode: Element, params: UseDragParams) {
|
||||
|
||||
return {
|
||||
nodes: get(store.nodes),
|
||||
nodesLookup: get(store.nodesLookup),
|
||||
edges: get(store.edges),
|
||||
nodeExtent: get(store.nodeExtent),
|
||||
snapGrid: snapGrid ? snapGrid : [0, 0],
|
||||
|
||||
@@ -17,11 +17,18 @@
|
||||
typeof ResizeObserver === 'undefined'
|
||||
? null
|
||||
: new ResizeObserver((entries: ResizeObserverEntry[]) => {
|
||||
const updates = entries.map((entry: ResizeObserverEntry) => ({
|
||||
id: entry.target.getAttribute('data-id') as string,
|
||||
nodeElement: entry.target as HTMLDivElement,
|
||||
forceUpdate: true
|
||||
}));
|
||||
const updates = new Map();
|
||||
|
||||
entries.forEach((entry: ResizeObserverEntry) => {
|
||||
const id = entry.target.getAttribute('data-id') as string;
|
||||
|
||||
updates.set(id, {
|
||||
id,
|
||||
nodeElement: entry.target as HTMLDivElement,
|
||||
forceUpdate: true
|
||||
});
|
||||
});
|
||||
|
||||
updateNodeDimensions(updates);
|
||||
});
|
||||
|
||||
|
||||
@@ -56,15 +56,15 @@ export function getDerivedConnectionProps(
|
||||
currentConnection,
|
||||
store.connectionLineType,
|
||||
store.connectionMode,
|
||||
store.nodes,
|
||||
store.nodesLookup,
|
||||
store.viewport
|
||||
],
|
||||
([connection, connectionLineType, connectionMode, nodes, viewport]) => {
|
||||
([connection, connectionLineType, connectionMode, nodesLookup, viewport]) => {
|
||||
if (!connection.connectionStartHandle?.nodeId) {
|
||||
return initConnectionProps;
|
||||
}
|
||||
|
||||
const fromNode = nodes.find((n) => n.id === connection.connectionStartHandle?.nodeId);
|
||||
const fromNode = nodesLookup.get(connection.connectionStartHandle?.nodeId);
|
||||
const fromHandleBounds = fromNode?.[internalsSymbol]?.handleBounds;
|
||||
const handleBoundsStrict =
|
||||
fromHandleBounds?.[connection.connectionStartHandle.type || 'source'] || [];
|
||||
|
||||
@@ -9,17 +9,18 @@ export function getEdgeTree(store: SvelteFlowStoreState) {
|
||||
[
|
||||
store.edges,
|
||||
store.nodes,
|
||||
store.nodesLookup,
|
||||
store.onlyRenderVisibleElements,
|
||||
store.viewport,
|
||||
store.width,
|
||||
store.height
|
||||
],
|
||||
([edges, nodes, onlyRenderVisibleElements, viewport, width, height]) => {
|
||||
([edges, , nodesLookup, onlyRenderVisibleElements, viewport, width, height]) => {
|
||||
const visibleEdges =
|
||||
onlyRenderVisibleElements && width && height
|
||||
? edges.filter((edge) => {
|
||||
const sourceNode = nodes.find((node) => node.id === edge.source);
|
||||
const targetNode = nodes.find((node) => node.id === edge.target);
|
||||
const sourceNode = nodesLookup.get(edge.source);
|
||||
const targetNode = nodesLookup.get(edge.target);
|
||||
|
||||
return (
|
||||
sourceNode &&
|
||||
@@ -40,11 +41,11 @@ export function getEdgeTree(store: SvelteFlowStoreState) {
|
||||
);
|
||||
|
||||
return derived(
|
||||
[visibleEdges, store.nodes, store.connectionMode, store.onError],
|
||||
([visibleEdges, nodes, connectionMode, onError]) => {
|
||||
[visibleEdges, store.nodes, store.nodesLookup, store.connectionMode, store.onError],
|
||||
([visibleEdges, , nodesLookup, connectionMode, onError]) => {
|
||||
const layoutedEdges = visibleEdges.reduce<EdgeLayouted[]>((res, edge) => {
|
||||
const sourceNode = nodes.find((node) => node.id === edge.source);
|
||||
const targetNode = nodes.find((node) => node.id === edge.target);
|
||||
const sourceNode = nodesLookup.get(edge.source);
|
||||
const targetNode = nodesLookup.get(edge.target);
|
||||
|
||||
if (!sourceNode || !targetNode) {
|
||||
return res;
|
||||
@@ -70,7 +71,7 @@ export function getEdgeTree(store: SvelteFlowStoreState) {
|
||||
return res;
|
||||
}, []);
|
||||
|
||||
const groupedEdges = groupEdgesByZLevel<EdgeLayouted>(layoutedEdges, nodes, false);
|
||||
const groupedEdges = groupEdgesByZLevel<EdgeLayouted>(layoutedEdges, nodesLookup, false);
|
||||
|
||||
return groupedEdges;
|
||||
}
|
||||
|
||||
@@ -86,10 +86,11 @@ export function createStore({
|
||||
});
|
||||
};
|
||||
|
||||
function updateNodeDimensions(updates: NodeDimensionUpdate[]) {
|
||||
function updateNodeDimensions(updates: Map<string, NodeDimensionUpdate>) {
|
||||
const nextNodes = updateNodeDimensionsSystem(
|
||||
updates,
|
||||
get(store.nodes),
|
||||
get(store.nodesLookup),
|
||||
get(store.domNode),
|
||||
get(store.nodeOrigin)
|
||||
);
|
||||
|
||||
@@ -59,7 +59,11 @@ export const getInitialStore = ({
|
||||
height?: number;
|
||||
fitView?: boolean;
|
||||
}) => {
|
||||
const nextNodes = updateNodes(nodes, [], { nodeOrigin: [0, 0], elevateNodesOnSelect: false });
|
||||
const nodesLookup = new Map<string, Node>();
|
||||
const nextNodes = updateNodes(nodes, nodesLookup, {
|
||||
nodeOrigin: [0, 0],
|
||||
elevateNodesOnSelect: false
|
||||
});
|
||||
|
||||
let viewport: Viewport = { x: 0, y: 0, zoom: 1 };
|
||||
|
||||
@@ -75,7 +79,8 @@ export const getInitialStore = ({
|
||||
|
||||
return {
|
||||
flowId: writable<string | null>(null),
|
||||
nodes: createNodesStore(nextNodes),
|
||||
nodes: createNodesStore(nextNodes, nodesLookup),
|
||||
nodesLookup: readable<Map<string, Node>>(nodesLookup),
|
||||
visibleNodes: readable<Node[]>([]),
|
||||
edges: createEdgesStore(edges),
|
||||
edgeTree: readable<GroupedEdges<EdgeLayouted>[]>([]),
|
||||
|
||||
@@ -27,7 +27,7 @@ export type SvelteFlowStoreActions = {
|
||||
setTranslateExtent: (extent: CoordinateExtent) => void;
|
||||
fitView: (options?: FitViewOptions) => boolean;
|
||||
updateNodePositions: UpdateNodePositions;
|
||||
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void;
|
||||
updateNodeDimensions: (updates: Map<string, NodeDimensionUpdate>) => void;
|
||||
unselectNodesAndEdges: (params?: { nodes?: Node[]; edges?: Edge[] }) => void;
|
||||
addSelectedNodes: (ids: string[]) => void;
|
||||
addSelectedEdges: (ids: string[]) => void;
|
||||
|
||||
@@ -111,7 +111,8 @@ export type NodeStoreOptions = {
|
||||
// we are creating a custom store for the internals nodes in order to update the zIndex and positionAbsolute.
|
||||
// The user only passes in relative positions, so we need to calculate the absolute positions based on the parent nodes.
|
||||
export const createNodesStore = (
|
||||
nodes: Node[]
|
||||
nodes: Node[],
|
||||
nodesLookup: Map<string, Node>
|
||||
): {
|
||||
subscribe: (this: void, run: Subscriber<Node[]>) => Unsubscriber;
|
||||
update: (this: void, updater: Updater<Node[]>) => void;
|
||||
@@ -125,7 +126,7 @@ export const createNodesStore = (
|
||||
let elevateNodesOnSelect = true;
|
||||
|
||||
const _set = (nds: Node[]): Node[] => {
|
||||
const nextNodes = updateNodes(nds, value, {
|
||||
const nextNodes = updateNodes(nds, nodesLookup, {
|
||||
elevateNodesOnSelect,
|
||||
defaults
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user