refactor: performance

This commit is contained in:
2026-03-12 21:01:43 +01:00
parent 92fdba7eef
commit 029bab8917
9 changed files with 109 additions and 47 deletions

View File

@@ -31,7 +31,7 @@ import {
import { useTheme } from '@/lib/themeContext'
import { usePlatform } from '@/app/kosmos/KosmosContext'
import { useCanvasGraph } from '@/app/canvas/useCanvasGraph'
import { getExampleGraph } from '@/app/canvas/canvasGraphUtils'
import { getExampleGraph, backfillEdgeTargetTypes } from '@/app/canvas/canvasGraphUtils'
import { ContextMenu, ContextMenuTrigger } from '@/components/ui/context-menu'
import { CanvasContextMenuContent } from '@/app/canvas/CanvasContextMenuContent'
import { useCanvasConnectionPath } from '@/app/canvas/useCanvasConnectionPath'
@@ -189,6 +189,9 @@ export function CanvasPage({ projectId }: CanvasPageProps) {
const nodesRef = useRef(nodes)
nodesRef.current = nodes
const graphRef = useRef<{ nodes: AppNode[]; edges: AppEdge[] }>({ nodes: [], edges: [] })
graphRef.current.nodes = nodes
graphRef.current.edges = edges
const [apiTodosCount, setApiTodosCount] = React.useState<number | null>(null)
React.useEffect(() => {
@@ -244,7 +247,12 @@ export function CanvasPage({ projectId }: CanvasPageProps) {
)
const onConnect = useCallback(
(params: Connection) => setEdges((eds) => addEdge(params, eds)),
(params: Connection) => {
const targetType =
nodesRef.current.find((n) => n.id === params.target)?.type ?? ''
const conn = { ...params, data: { targetType } as Record<string, unknown> }
setEdges((eds) => addEdge(conn, eds))
},
[setEdges]
)
@@ -324,7 +332,9 @@ export function CanvasPage({ projectId }: CanvasPageProps) {
toast.error('Invalid file: expected nodes and edges arrays')
return
}
setStateImmediate({ nodes: state.nodes as AppNode[], edges: state.edges as AppEdge[] })
const nodes = state.nodes as AppNode[]
const edges = backfillEdgeTargetTypes(nodes, state.edges as AppEdge[])
setStateImmediate({ nodes, edges })
if (state.version != null && state.version > PROJECT_VERSION) {
toast.error('Project was created with a newer app version')
} else {
@@ -393,8 +403,8 @@ export function CanvasPage({ projectId }: CanvasPageProps) {
}, [])
const graphContextValue = useMemo(
() => ({ nodes, setNodes, edges, setEdges }),
[nodes, setNodes, edges, setEdges]
() => ({ setNodes, setEdges, graphRef, edges }),
[setNodes, setEdges, edges]
)
const connectionPathContextValue = useMemo(
() => ({
@@ -438,18 +448,36 @@ export function CanvasPage({ projectId }: CanvasPageProps) {
]
)
const nodesForFlow = useMemo(
() =>
nodes.map((n) => ({
const prevNodesRef = useRef<AppNode[]>([])
const prevNodesForFlowRef = useRef<Node[]>([])
const nodesForFlow = useMemo(() => {
const prev = prevNodesRef.current
if (nodes === prev) return prevNodesForFlowRef.current
const prevById = new Map(prev.map((n) => [n.id, n]))
const prevWrappedById = new Map(
prevNodesForFlowRef.current.map((w, i) => [prev[i]?.id, w])
)
const result = nodes.map((n) => {
const prevNode = prevById.get(n.id)
if (prevNode === n && prevWrappedById.has(n.id)) {
return prevWrappedById.get(n.id)!
}
return {
...n,
className: [n.className, 'nowheel'].filter(Boolean).join(' '),
})),
[nodes]
)
}
})
prevNodesRef.current = nodes
prevNodesForFlowRef.current = result
return result
}, [nodes])
const edgesForFlow = useMemo(
() =>
edges.map((e) => {
const targetType = nodes.find((nd) => nd.id === e.target)?.type ?? ''
const targetType =
(typeof e.data === 'object' && e.data !== null && (e.data as Record<string, unknown>).targetType != null
? (e.data as Record<string, unknown>).targetType
: '') as string
const connectionLabel = getConnectionLabelForTarget(targetType)
const baseData =
typeof e.data === 'object' && e.data !== null ? (e.data as Record<string, unknown>) : {}
@@ -458,7 +486,7 @@ export function CanvasPage({ projectId }: CanvasPageProps) {
data: { ...baseData, connectionLabel },
}
}),
[edges, nodes]
[edges]
)
const onContextMenuCapture = useCallback((ev: React.MouseEvent) => {