mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 05:18:12 +08:00
Speed up graph view frontend by removing a querySelectorAll hot path (#1475)
* Reduce query selector all that was slowing perf * Speed up double iteration of filter map with flatMap --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
2515620a77
commit
ee95dac74e
@@ -40,6 +40,9 @@
|
|||||||
let searchTerm = "";
|
let searchTerm = "";
|
||||||
let nodeListLocation: { x: number; y: number } | undefined = undefined;
|
let nodeListLocation: { x: number; y: number } | undefined = undefined;
|
||||||
|
|
||||||
|
let inputs: SVGSVGElement[][] = [];
|
||||||
|
let outputs: SVGSVGElement[][] = [];
|
||||||
|
|
||||||
$: watchNodes($nodeGraph.nodes);
|
$: watchNodes($nodeGraph.nodes);
|
||||||
|
|
||||||
$: gridSpacing = calculateGridSpacing(transform.scale);
|
$: gridSpacing = calculateGridSpacing(transform.scale);
|
||||||
@@ -126,17 +129,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function watchNodes(nodes: FrontendNode[]) {
|
async function watchNodes(nodes: FrontendNode[]) {
|
||||||
|
nodes.forEach((_, index) => {
|
||||||
|
if (!inputs[index]) inputs[index] = [];
|
||||||
|
if (!outputs[index]) outputs[index] = [];
|
||||||
|
});
|
||||||
|
|
||||||
selected = selected.filter((id) => nodes.find((node) => node.id === id));
|
selected = selected.filter((id) => nodes.find((node) => node.id === id));
|
||||||
await refreshLinks();
|
await refreshLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveLink(link: FrontendNodeLink, containerBounds: HTMLDivElement): { nodeOutput: SVGSVGElement | undefined; nodeInput: SVGSVGElement | undefined } {
|
function resolveLink(link: FrontendNodeLink): { nodeOutput: SVGSVGElement | undefined; nodeInput: SVGSVGElement | undefined } {
|
||||||
const outputIndex = Number(link.linkStartOutputIndex);
|
const outputIndex = Number(link.linkStartOutputIndex);
|
||||||
const inputIndex = Number(link.linkEndInputIndex);
|
const inputIndex = Number(link.linkEndInputIndex);
|
||||||
|
|
||||||
const nodeOutputConnectors = containerBounds.querySelectorAll(`[data-node="${String(link.linkStart)}"] [data-port="output"]`) || undefined;
|
const nodeOutputConnectors = outputs[$nodeGraph.nodes.findIndex((node) => node.id === link.linkStart)];
|
||||||
|
const nodeInputConnectors = inputs[$nodeGraph.nodes.findIndex((node) => node.id === link.linkEnd)] || undefined;
|
||||||
const nodeInputConnectors = containerBounds.querySelectorAll(`[data-node="${String(link.linkEnd)}"] [data-port="input"]`) || undefined;
|
|
||||||
|
|
||||||
const nodeOutput = nodeOutputConnectors?.[outputIndex] as SVGSVGElement | undefined;
|
const nodeOutput = nodeOutputConnectors?.[outputIndex] as SVGSVGElement | undefined;
|
||||||
const nodeInput = nodeInputConnectors?.[inputIndex] as SVGSVGElement | undefined;
|
const nodeInput = nodeInputConnectors?.[inputIndex] as SVGSVGElement | undefined;
|
||||||
@@ -146,12 +153,9 @@
|
|||||||
async function refreshLinks() {
|
async function refreshLinks() {
|
||||||
await tick();
|
await tick();
|
||||||
|
|
||||||
if (!nodesContainer) return;
|
|
||||||
const theNodesContainer = nodesContainer;
|
|
||||||
|
|
||||||
const links = $nodeGraph.links;
|
const links = $nodeGraph.links;
|
||||||
nodeLinkPaths = links.flatMap((link, index) => {
|
nodeLinkPaths = links.flatMap((link, index) => {
|
||||||
const { nodeInput, nodeOutput } = resolveLink(link, theNodesContainer);
|
const { nodeInput, nodeOutput } = resolveLink(link);
|
||||||
if (!nodeInput || !nodeOutput) return [];
|
if (!nodeInput || !nodeOutput) return [];
|
||||||
if (disconnecting?.linkIndex === index) return [];
|
if (disconnecting?.linkIndex === index) return [];
|
||||||
const linkStart = $nodeGraph.nodes.find((node) => node.id === link.linkStart)?.displayName === "Layer";
|
const linkStart = $nodeGraph.nodes.find((node) => node.id === link.linkStart)?.displayName === "Layer";
|
||||||
@@ -463,7 +467,7 @@
|
|||||||
|
|
||||||
// Find the link that the node has been dragged on top of
|
// Find the link that the node has been dragged on top of
|
||||||
const link = $nodeGraph.links.find((link): boolean => {
|
const link = $nodeGraph.links.find((link): boolean => {
|
||||||
const { nodeInput, nodeOutput } = resolveLink(link, theNodesContainer);
|
const { nodeInput, nodeOutput } = resolveLink(link);
|
||||||
if (!nodeInput || !nodeOutput) return false;
|
if (!nodeInput || !nodeOutput) return false;
|
||||||
|
|
||||||
const wireCurveLocations = buildWirePathLocations(nodeOutput.getBoundingClientRect(), nodeInput.getBoundingClientRect(), false, false);
|
const wireCurveLocations = buildWirePathLocations(nodeOutput.getBoundingClientRect(), nodeInput.getBoundingClientRect(), false, false);
|
||||||
@@ -661,7 +665,7 @@
|
|||||||
<!-- Layers and nodes -->
|
<!-- Layers and nodes -->
|
||||||
<div class="layers-and-nodes" style:transform={`scale(${transform.scale}) translate(${transform.x}px, ${transform.y}px)`} style:transform-origin={`0 0`} bind:this={nodesContainer}>
|
<div class="layers-and-nodes" style:transform={`scale(${transform.scale}) translate(${transform.x}px, ${transform.y}px)`} style:transform-origin={`0 0`} bind:this={nodesContainer}>
|
||||||
<!-- Layers -->
|
<!-- Layers -->
|
||||||
{#each $nodeGraph.nodes.filter((node) => node.displayName === "Layer") as node (String(node.id))}
|
{#each $nodeGraph.nodes.flatMap((node, nodeIndex) => (node.displayName === "Layer" ? [{ node, nodeIndex }] : [])) as { node, nodeIndex } (String(node.id))}
|
||||||
{@const clipPathId = `${Math.random()}`.substring(2)}
|
{@const clipPathId = `${Math.random()}`.substring(2)}
|
||||||
{@const stackDatainput = node.exposedInputs[0]}
|
{@const stackDatainput = node.exposedInputs[0]}
|
||||||
<div
|
<div
|
||||||
@@ -687,6 +691,7 @@
|
|||||||
data-datatype={node.primaryInput?.dataType}
|
data-datatype={node.primaryInput?.dataType}
|
||||||
style:--data-color={`var(--color-data-${node.primaryInput?.dataType})`}
|
style:--data-color={`var(--color-data-${node.primaryInput?.dataType})`}
|
||||||
style:--data-color-dim={`var(--color-data-${node.primaryInput?.dataType}-dim)`}
|
style:--data-color-dim={`var(--color-data-${node.primaryInput?.dataType}-dim)`}
|
||||||
|
bind:this={inputs[nodeIndex][0]}
|
||||||
>
|
>
|
||||||
<title>{node.primaryInput} data</title>
|
<title>{node.primaryInput} data</title>
|
||||||
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" />
|
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" />
|
||||||
@@ -705,6 +710,7 @@
|
|||||||
data-datatype={node.primaryOutput.dataType}
|
data-datatype={node.primaryOutput.dataType}
|
||||||
style:--data-color={`var(--color-data-${node.primaryOutput.dataType})`}
|
style:--data-color={`var(--color-data-${node.primaryOutput.dataType})`}
|
||||||
style:--data-color-dim={`var(--color-data-${node.primaryOutput.dataType}-dim)`}
|
style:--data-color-dim={`var(--color-data-${node.primaryOutput.dataType}-dim)`}
|
||||||
|
bind:this={outputs[nodeIndex][0]}
|
||||||
>
|
>
|
||||||
<title>{node.primaryOutput.dataType} data</title>
|
<title>{node.primaryOutput.dataType} data</title>
|
||||||
<path d="M0,2.953,2.521,1.259a2.649,2.649,0,0,1,2.959,0L8,2.953V8H0Z" />
|
<path d="M0,2.953,2.521,1.259a2.649,2.649,0,0,1,2.959,0L8,2.953V8H0Z" />
|
||||||
@@ -718,6 +724,7 @@
|
|||||||
data-datatype={stackDatainput.dataType}
|
data-datatype={stackDatainput.dataType}
|
||||||
style:--data-color={`var(--color-data-${stackDatainput.dataType})`}
|
style:--data-color={`var(--color-data-${stackDatainput.dataType})`}
|
||||||
style:--data-color-dim={`var(--color-data-${stackDatainput.dataType}-dim)`}
|
style:--data-color-dim={`var(--color-data-${stackDatainput.dataType}-dim)`}
|
||||||
|
bind:this={inputs[nodeIndex][1]}
|
||||||
>
|
>
|
||||||
<title>{stackDatainput.dataType} data</title>
|
<title>{stackDatainput.dataType} data</title>
|
||||||
<path d="M0,0H8V8L5.479,6.319a2.666,2.666,0,0,0-2.959,0L0,8Z" />
|
<path d="M0,0H8V8L5.479,6.319a2.666,2.666,0,0,0-2.959,0L0,8Z" />
|
||||||
@@ -737,7 +744,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
<!-- Nodes -->
|
<!-- Nodes -->
|
||||||
{#each $nodeGraph.nodes.filter((node) => node.displayName !== "Layer") as node (String(node.id))}
|
{#each $nodeGraph.nodes.flatMap((node, nodeIndex) => (node.displayName !== "Layer" ? [{ node, nodeIndex }] : [])) as { node, nodeIndex } (String(node.id))}
|
||||||
{@const exposedInputsOutputs = [...node.exposedInputs, ...node.exposedOutputs]}
|
{@const exposedInputsOutputs = [...node.exposedInputs, ...node.exposedOutputs]}
|
||||||
{@const clipPathId = `${Math.random()}`.substring(2)}
|
{@const clipPathId = `${Math.random()}`.substring(2)}
|
||||||
<div
|
<div
|
||||||
@@ -780,6 +787,7 @@
|
|||||||
data-datatype={node.primaryInput?.dataType}
|
data-datatype={node.primaryInput?.dataType}
|
||||||
style:--data-color={`var(--color-data-${node.primaryInput?.dataType})`}
|
style:--data-color={`var(--color-data-${node.primaryInput?.dataType})`}
|
||||||
style:--data-color-dim={`var(--color-data-${node.primaryInput?.dataType}-dim)`}
|
style:--data-color-dim={`var(--color-data-${node.primaryInput?.dataType}-dim)`}
|
||||||
|
bind:this={inputs[nodeIndex][0]}
|
||||||
>
|
>
|
||||||
<title>{node.primaryInput} data</title>
|
<title>{node.primaryInput} data</title>
|
||||||
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" />
|
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" />
|
||||||
@@ -795,6 +803,7 @@
|
|||||||
data-datatype={parameter.dataType}
|
data-datatype={parameter.dataType}
|
||||||
style:--data-color={`var(--color-data-${parameter.dataType})`}
|
style:--data-color={`var(--color-data-${parameter.dataType})`}
|
||||||
style:--data-color-dim={`var(--color-data-${parameter.dataType}-dim)`}
|
style:--data-color-dim={`var(--color-data-${parameter.dataType}-dim)`}
|
||||||
|
bind:this={inputs[nodeIndex][index + 1]}
|
||||||
>
|
>
|
||||||
<title>{parameter.dataType} data</title>
|
<title>{parameter.dataType} data</title>
|
||||||
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" />
|
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" />
|
||||||
@@ -813,12 +822,13 @@
|
|||||||
data-datatype={node.primaryOutput.dataType}
|
data-datatype={node.primaryOutput.dataType}
|
||||||
style:--data-color={`var(--color-data-${node.primaryOutput.dataType})`}
|
style:--data-color={`var(--color-data-${node.primaryOutput.dataType})`}
|
||||||
style:--data-color-dim={`var(--color-data-${node.primaryOutput.dataType}-dim)`}
|
style:--data-color-dim={`var(--color-data-${node.primaryOutput.dataType}-dim)`}
|
||||||
|
bind:this={outputs[nodeIndex][0]}
|
||||||
>
|
>
|
||||||
<title>{node.primaryOutput.dataType} data</title>
|
<title>{node.primaryOutput.dataType} data</title>
|
||||||
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" />
|
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
{#each node.exposedOutputs as parameter}
|
{#each node.exposedOutputs as parameter, outputIndex}
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 8 8"
|
viewBox="0 0 8 8"
|
||||||
@@ -827,6 +837,7 @@
|
|||||||
data-datatype={parameter.dataType}
|
data-datatype={parameter.dataType}
|
||||||
style:--data-color={`var(--color-data-${parameter.dataType})`}
|
style:--data-color={`var(--color-data-${parameter.dataType})`}
|
||||||
style:--data-color-dim={`var(--color-data-${parameter.dataType}-dim)`}
|
style:--data-color-dim={`var(--color-data-${parameter.dataType}-dim)`}
|
||||||
|
bind:this={outputs[nodeIndex][outputIndex + 1]}
|
||||||
>
|
>
|
||||||
<title>{parameter.dataType} data</title>
|
<title>{parameter.dataType} data</title>
|
||||||
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" />
|
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" />
|
||||||
|
|||||||
Reference in New Issue
Block a user