From 662974b22279d558d40e770ae039937b12e5714f Mon Sep 17 00:00:00 2001 From: Alexander Brown Date: Tue, 2 Dec 2025 21:28:52 -0800 Subject: [PATCH] Speed: Remove some optimizations that weren't optimizing (#6209) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Simplify the TransformPane. ## Changes - **What**: Remove the settling and culling composables. Gets rid of a frequent event emission and some event handling addition/removals. ## Review Focus In testing with a huge workflow in Vue mode, it was a lot faster without these than with. Can you check to see if you experience the same benefits? ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6209-Speed-Remove-some-optimizations-that-weren-t-optimizing-2946d73d3650815197a4df3c58a61575) by [Unito](https://www.unito.io) --------- Co-authored-by: github-actions --- .../vue-nodes-lod-active-chromium-linux.png | Bin 36308 -> 39181 bytes packages/design-system/src/css/style.css | 9 - src/components/graph/GraphCanvas.vue | 3 - src/composables/graph/useViewportCulling.ts | 103 ----------- .../layout/__tests__/TransformPane.test.ts | 87 +-------- .../core/layout/transform/TransformPane.vue | 26 +-- .../layout/transform/useTransformSettling.ts | 84 --------- .../graph/useTransformSettling.test.ts | 167 ------------------ 8 files changed, 2 insertions(+), 477 deletions(-) delete mode 100644 src/composables/graph/useViewportCulling.ts delete mode 100644 src/renderer/core/layout/transform/useTransformSettling.ts delete mode 100644 tests-ui/tests/composables/graph/useTransformSettling.test.ts diff --git a/browser_tests/tests/vueNodes/nodeStates/lod.spec.ts-snapshots/vue-nodes-lod-active-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/lod.spec.ts-snapshots/vue-nodes-lod-active-chromium-linux.png index 4dd10e50ec3f524468259998b142087e3d03e1e3..f0d38ee0a78d262816fddf5d5b4ed90e27c0c366 100644 GIT binary patch literal 39181 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 literal 36308 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 @@ -118,7 +117,6 @@ import TopbarBadges from '@/components/topbar/TopbarBadges.vue' import WorkflowTabs from '@/components/topbar/WorkflowTabs.vue' import { useChainCallback } from '@/composables/functional/useChainCallback' import type { VueNodeData } from '@/composables/graph/useGraphNodeManager' -import { useViewportCulling } from '@/composables/graph/useViewportCulling' import { useVueNodeLifecycle } from '@/composables/graph/useVueNodeLifecycle' import { useNodeBadge } from '@/composables/node/useNodeBadge' import { useCanvasDrop } from '@/composables/useCanvasDrop' @@ -202,7 +200,6 @@ const { shouldRenderVueNodes } = useVueFeatureFlags() // Vue node system const vueNodeLifecycle = useVueNodeLifecycle() -const { handleTransformUpdate } = useViewportCulling() const handleVueNodeLifecycleReset = async () => { if (shouldRenderVueNodes.value) { diff --git a/src/composables/graph/useViewportCulling.ts b/src/composables/graph/useViewportCulling.ts deleted file mode 100644 index 30cf82e56..000000000 --- a/src/composables/graph/useViewportCulling.ts +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Vue Nodes Viewport Culling - * - * Principles: - * 1. Query DOM directly using data attributes (no cache to maintain) - * 2. Set display none on element to avoid cascade resolution overhead - * 3. Only run when transform changes (event driven) - */ -import { createSharedComposable, useThrottleFn } from '@vueuse/core' -import { computed } from 'vue' - -import { useVueNodeLifecycle } from '@/composables/graph/useVueNodeLifecycle' -import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode' -import { useCanvasStore } from '@/renderer/core/canvas/canvasStore' -import { app } from '@/scripts/app' - -type Bounds = [left: number, right: number, top: number, bottom: number] - -function getNodeBounds(node: LGraphNode): Bounds { - const [nodeLeft, nodeTop] = node.pos - const nodeRight = nodeLeft + node.size[0] - const nodeBottom = nodeTop + node.size[1] - return [nodeLeft, nodeRight, nodeTop, nodeBottom] -} - -function viewportEdges( - canvas: ReturnType['canvas'] -): Bounds | undefined { - if (!canvas) { - return - } - const ds = canvas.ds - const viewport_width = canvas.canvas.width - const viewport_height = canvas.canvas.height - const margin = 500 * ds.scale - - const [xOffset, yOffset] = ds.offset - - const leftEdge = -margin / ds.scale - xOffset - const rightEdge = (viewport_width + margin) / ds.scale - xOffset - const topEdge = -margin / ds.scale - yOffset - const bottomEdge = (viewport_height + margin) / ds.scale - yOffset - return [leftEdge, rightEdge, topEdge, bottomEdge] -} - -function boundsIntersect(boxA: Bounds, boxB: Bounds): boolean { - const [aLeft, aRight, aTop, aBottom] = boxA - const [bLeft, bRight, bTop, bBottom] = boxB - - const leftOf = aRight < bLeft - const rightOf = aLeft > bRight - const above = aBottom < bTop - const below = aTop > bBottom - return !(leftOf || rightOf || above || below) -} - -function useViewportCullingIndividual() { - const canvasStore = useCanvasStore() - const { nodeManager } = useVueNodeLifecycle() - - const viewport = computed(() => viewportEdges(canvasStore.canvas)) - - function inViewport(node: LGraphNode | undefined): boolean { - if (!viewport.value || !node) { - return true - } - const nodeBounds = getNodeBounds(node) - return boundsIntersect(nodeBounds, viewport.value) - } - - /** - * Update visibility of all nodes based on viewport - * Queries DOM directly - no cache maintenance needed - */ - function updateVisibility() { - if (!nodeManager.value || !app.canvas) return // load bearing app.canvas check for workflows being loaded. - - const nodeElements = document.querySelectorAll('[data-node-id]') - for (const element of nodeElements) { - const nodeId = element.getAttribute('data-node-id') - if (!nodeId) continue - - const node = nodeManager.value.getNode(nodeId) - if (!node) continue - - const displayValue = inViewport(node) ? '' : 'none' - if ( - element instanceof HTMLElement && - element.style.display !== displayValue - ) { - element.style.display = displayValue - } - } - } - - const handleTransformUpdate = useThrottleFn(() => updateVisibility, 100, true) - - return { handleTransformUpdate } -} - -export const useViewportCulling = createSharedComposable( - useViewportCullingIndividual -) diff --git a/src/renderer/core/layout/__tests__/TransformPane.test.ts b/src/renderer/core/layout/__tests__/TransformPane.test.ts index 310294c5c..4876115b9 100644 --- a/src/renderer/core/layout/__tests__/TransformPane.test.ts +++ b/src/renderer/core/layout/__tests__/TransformPane.test.ts @@ -115,89 +115,6 @@ describe('TransformPane', () => { const transformState = useTransformState() expect(transformState.syncWithCanvas).toHaveBeenCalledWith(mockCanvas) }) - - it('should emit transform update timing', async () => { - const mockCanvas = createMockCanvas() - const wrapper = mount(TransformPane, { - props: { - canvas: mockCanvas - } - }) - - await nextTick() - - // Allow RAF to execute - vi.advanceTimersToNextFrame() - - expect(wrapper.emitted('transformUpdate')).toBeTruthy() - }) - }) - - describe('canvas event listeners', () => { - it('should add event listeners to canvas on mount', async () => { - const mockCanvas = createMockCanvas() - mount(TransformPane, { - props: { - canvas: mockCanvas - } - }) - - await nextTick() - - expect(mockCanvas.canvas.addEventListener).toHaveBeenCalledWith( - 'wheel', - expect.any(Function), - expect.any(Object) - ) - expect(mockCanvas.canvas.addEventListener).not.toHaveBeenCalledWith( - 'pointerdown', - expect.any(Function), - expect.any(Object) - ) - expect(mockCanvas.canvas.addEventListener).not.toHaveBeenCalledWith( - 'pointerup', - expect.any(Function), - expect.any(Object) - ) - expect(mockCanvas.canvas.addEventListener).not.toHaveBeenCalledWith( - 'pointercancel', - expect.any(Function), - expect.any(Object) - ) - }) - - it('should remove event listeners on unmount', async () => { - const mockCanvas = createMockCanvas() - const wrapper = mount(TransformPane, { - props: { - canvas: mockCanvas - } - }) - - await nextTick() - wrapper.unmount() - - expect(mockCanvas.canvas.removeEventListener).toHaveBeenCalledWith( - 'wheel', - expect.any(Function), - expect.any(Object) - ) - expect(mockCanvas.canvas.removeEventListener).not.toHaveBeenCalledWith( - 'pointerdown', - expect.any(Function), - expect.any(Object) - ) - expect(mockCanvas.canvas.removeEventListener).not.toHaveBeenCalledWith( - 'pointerup', - expect.any(Function), - expect.any(Object) - ) - expect(mockCanvas.canvas.removeEventListener).not.toHaveBeenCalledWith( - 'pointercancel', - expect.any(Function), - expect.any(Object) - ) - }) }) describe('interaction state management', () => { @@ -214,9 +131,7 @@ describe('TransformPane', () => { const transformPane = wrapper.find('[data-testid="transform-pane"]') // Initially should not have interacting class - expect(transformPane.classes()).not.toContain( - 'transform-pane--interacting' - ) + expect(transformPane.classes()).not.toContain('will-change-transform') }) it('should handle pointer events for node delegation', async () => { diff --git a/src/renderer/core/layout/transform/TransformPane.vue b/src/renderer/core/layout/transform/TransformPane.vue index edc683572..b39f67140 100644 --- a/src/renderer/core/layout/transform/TransformPane.vue +++ b/src/renderer/core/layout/transform/TransformPane.vue @@ -1,12 +1,7 @@