fix(editor): Fix nodes and connection debouncing during execution (no-changelog) (#14208)

This commit is contained in:
Alex Grozav
2025-03-27 11:59:04 +02:00
committed by GitHub
parent 5f4e56f75b
commit a4a34a2745
4 changed files with 60 additions and 93 deletions

View File

@@ -1,15 +1,14 @@
<script setup lang="ts">
import Canvas from '@/components/canvas/Canvas.vue';
import type { WatchStopHandle } from 'vue';
import { computed, ref, toRef, useCssModule, watch } from 'vue';
import { computed, ref, toRef, useCssModule } from 'vue';
import type { Workflow } from 'n8n-workflow';
import type { IWorkflowDb } from '@/Interface';
import { useCanvasMapping } from '@/composables/useCanvasMapping';
import type { EventBus } from '@n8n/utils/event-bus';
import { createEventBus } from '@n8n/utils/event-bus';
import type { CanvasConnection, CanvasEventBusEvents, CanvasNode } from '@/types';
import type { CanvasEventBusEvents } from '@/types';
import { useVueFlow } from '@vue-flow/core';
import { debounce } from 'lodash-es';
import { debouncedRef } from '@vueuse/core';
defineOptions({
inheritAttrs: false,
@@ -62,56 +61,8 @@ onNodesInitialized(() => {
}
});
// Debounced versions of nodes and connections and watchers
const nodesDebounced = ref<CanvasNode[]>([]);
const connectionsDebounced = ref<CanvasConnection[]>([]);
const debounceNodesWatcher = ref<WatchStopHandle>();
const debounceConnectionsWatcher = ref<WatchStopHandle>();
// Update debounce watchers when execution state changes
watch(() => props.executing, setupDebouncedWatchers, { immediate: true });
/**
* Sets up debounced watchers for nodes and connections
* Uses different debounce times based on execution state:
* - During execution: Debounce updates to reduce performance impact for large number of nodes/items
* - Otherwise: Update immediately
*/
function setupDebouncedWatchers() {
// Clear existing watchers if they exist
debounceNodesWatcher.value?.();
debounceConnectionsWatcher.value?.();
// Configure debounce parameters based on execution state
const debounceTime = props.executing ? 200 : 0;
const maxWait = props.executing ? 50 : 0;
// Set up debounced watcher for nodes
debounceNodesWatcher.value = watch(
mappedNodes,
debounce(
(value) => {
nodesDebounced.value = value;
},
debounceTime,
{ maxWait },
),
{ immediate: true, deep: true },
);
// Set up debounced watcher for connections
debounceConnectionsWatcher.value = watch(
mappedConnections,
debounce(
(value) => {
connectionsDebounced.value = value;
},
debounceTime,
{ maxWait },
),
{ immediate: true, deep: true },
);
}
const mappedNodesDebounced = debouncedRef(mappedNodes, 200, { maxWait: 50 });
const mappedConnectionsDebounced = debouncedRef(mappedConnections, 200, { maxWait: 50 });
</script>
<template>
@@ -120,8 +71,8 @@ function setupDebouncedWatchers() {
<Canvas
v-if="workflow"
:id="id"
:nodes="nodesDebounced"
:connections="connectionsDebounced"
:nodes="executing ? mappedNodesDebounced : mappedNodes"
:connections="executing ? mappedConnectionsDebounced : mappedConnections"
:event-bus="eventBus"
:read-only="readOnly"
v-bind="$attrs"