mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 16:02:28 +00:00
fix: improve computeAssetNodes rendering caching and performance (#6414)
* better caching for computeAssetNodes * only pass required fields * unecessary returns * type not necessary
This commit is contained in:
@@ -56,6 +56,7 @@
|
||||
import { ChangeTracker } from '$lib/svelte5Utils.svelte'
|
||||
import type { ModulesTestStates } from '../modulesTest.svelte'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import type { AssetWithAltAccessType } from '../assets/lib'
|
||||
|
||||
let useDataflow: Writable<boolean | undefined> = writable<boolean | undefined>(false)
|
||||
|
||||
@@ -388,13 +389,23 @@
|
||||
offset: n.data.offset ?? 0
|
||||
}))
|
||||
)
|
||||
let newNodes: (Node & NodeLayout)[] = layoutedNodes.map((n) => {
|
||||
return {
|
||||
...n,
|
||||
...graph.nodes[n.id]
|
||||
}
|
||||
})
|
||||
;[nodes, edges] = computeAssetNodes(newNodes, graph.edges)
|
||||
let newNodes: (Node & NodeLayout)[] = layoutedNodes.map((n) => ({ ...n, ...graph.nodes[n.id] }))
|
||||
|
||||
let assetNodesResult = computeAssetNodes(
|
||||
newNodes.map((n) => ({
|
||||
data: { assets: n.data?.assets as AssetWithAltAccessType[] },
|
||||
id: n.id,
|
||||
position: n.position
|
||||
}))
|
||||
)
|
||||
newNodes = [
|
||||
...newNodes.map((n) => ({ ...n, position: assetNodesResult.newNodePositions[n.id] })),
|
||||
...assetNodesResult.newAssetNodes
|
||||
]
|
||||
|
||||
nodes = newNodes
|
||||
edges = [...assetNodesResult.newAssetEdges, ...graph.edges]
|
||||
|
||||
await tick()
|
||||
height = Math.max(...nodes.map((n) => n.position.y + NODE.height + 100), minHeight)
|
||||
}
|
||||
|
||||
@@ -8,16 +8,23 @@
|
||||
export const assetDisplaysAsOutputInFlowGraph = (a: AssetWithAltAccessType) =>
|
||||
getAccessType(a) === 'w' || getAccessType(a) === 'rw'
|
||||
|
||||
let computeAssetNodesCache:
|
||||
| [(Node & NodeLayout)[], ReturnType<typeof computeAssetNodes>]
|
||||
| undefined
|
||||
let computeAssetNodesCache: [NodeDep[], ReturnType<typeof computeAssetNodes>] | undefined
|
||||
|
||||
export function computeAssetNodes(
|
||||
nodes: (Node & NodeLayout)[],
|
||||
edges: Edge[]
|
||||
): [(Node & NodeLayout)[], Edge[]] {
|
||||
if (nodes === computeAssetNodesCache?.[0]) return computeAssetNodesCache[1]
|
||||
type NodeDep = {
|
||||
data: object & { assets?: AssetWithAltAccessType[] | undefined }
|
||||
id: string
|
||||
position: { x: number; y: number }
|
||||
}
|
||||
|
||||
export function computeAssetNodes(nodes: NodeDep[]): {
|
||||
newAssetNodes: (Node & NodeLayout)[]
|
||||
newAssetEdges: Edge[]
|
||||
// Nodes need to be offset on the y axis to make space for the asset nodes
|
||||
newNodePositions: Record<string, { x: number; y: number }>
|
||||
} {
|
||||
if (computeAssetNodesCache && deepEqual(nodes, computeAssetNodesCache[0])) {
|
||||
return computeAssetNodesCache[1]
|
||||
}
|
||||
const MAX_ASSET_ROW_WIDTH = 300
|
||||
const ASSETS_OVERFLOWED_NODE_WIDTH = 25
|
||||
const allAssetNodes: (Node & NodeLayout)[] = []
|
||||
@@ -26,8 +33,8 @@
|
||||
const yPosMap: Record<number, { r?: true; w?: true }> = {}
|
||||
|
||||
for (const node of nodes) {
|
||||
if (node.type !== 'module' && node.type !== 'input2') continue
|
||||
const assets = node.data.assets ?? []
|
||||
if (!assets.length) continue
|
||||
|
||||
// Each asset can be displayed at the top and bottom
|
||||
// i.e once (R or W) or twice (RW)
|
||||
@@ -179,7 +186,10 @@
|
||||
}
|
||||
|
||||
// Shift all nodes to make space for the new asset nodes
|
||||
const sortedNewNodes = clone(nodes.sort((a, b) => a.position.y - b.position.y))
|
||||
const sortedNewNodes = nodes
|
||||
.map((n) => ({ position: { ...n.position }, id: n.id }))
|
||||
.sort((a, b) => a.position.y - b.position.y)
|
||||
|
||||
let currentYOffset = 0
|
||||
let prevYPos = NaN
|
||||
for (const node of sortedNewNodes) {
|
||||
@@ -191,10 +201,11 @@
|
||||
node.position.y += currentYOffset
|
||||
}
|
||||
|
||||
let ret: ReturnType<typeof computeAssetNodes> = [
|
||||
[...sortedNewNodes, ...allAssetNodes],
|
||||
[...edges, ...allAssetEdges]
|
||||
]
|
||||
let ret: ReturnType<typeof computeAssetNodes> = {
|
||||
newAssetNodes: allAssetNodes,
|
||||
newAssetEdges: allAssetEdges,
|
||||
newNodePositions: Object.fromEntries(sortedNewNodes.map((n) => [n.id, n.position]))
|
||||
}
|
||||
computeAssetNodesCache = [nodes, ret]
|
||||
return ret
|
||||
}
|
||||
@@ -215,12 +226,13 @@
|
||||
import { getContext } from 'svelte'
|
||||
import ExploreAssetButton, { assetCanBeExplored } from '../../../ExploreAssetButton.svelte'
|
||||
import { Tooltip } from '$lib/components/meltComponents'
|
||||
import { clone, pluralize } from '$lib/utils'
|
||||
import { pluralize } from '$lib/utils'
|
||||
import AssetGenericIcon from '$lib/components/icons/AssetGenericIcon.svelte'
|
||||
import type { Edge, Node } from '@xyflow/svelte'
|
||||
|
||||
import { NODE } from '../../util'
|
||||
import { userStore } from '$lib/stores'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
|
||||
interface Props {
|
||||
data: AssetN['data']
|
||||
|
||||
Reference in New Issue
Block a user