Skip to content

Commit

Permalink
fix(editor): Fix performance issues related to expressions and pinned…
Browse files Browse the repository at this point in the history
… data (#9882)

Co-authored-by: Mutasem Aldmour <mutasem@n8n.io>
  • Loading branch information
alexgrozav and mutdmour authored Jun 27, 2024
1 parent 2885091 commit 13d83f2
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 34 deletions.
31 changes: 14 additions & 17 deletions packages/editor-ui/src/components/NodeDetailsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
/>
<InputPanel
v-else-if="!isTriggerNode"
:workflow="workflow"
:workflow="workflowObject"
:can-link-runs="canLinkRuns"
:run-index="inputRun"
:linked-runs="linked"
Expand All @@ -85,7 +85,7 @@
<template #output>
<OutputPanel
data-test-id="output-panel"
:workflow="workflow"
:workflow="workflowObject"
:can-link-runs="canLinkRuns"
:run-index="outputRun"
:linked-runs="linked"
Expand Down Expand Up @@ -141,7 +141,7 @@
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed, watch } from 'vue';
import { createEventBus } from 'n8n-design-system/utils';
import type { IRunData, ConnectionTypes } from 'n8n-workflow';
import type { IRunData, ConnectionTypes, Workflow } from 'n8n-workflow';
import { jsonParse, NodeHelpers, NodeConnectionType } from 'n8n-workflow';
import type { IUpdateInformation, TargetItem } from '@/Interface';
Expand Down Expand Up @@ -171,8 +171,6 @@ import { useNodeHelpers } from '@/composables/useNodeHelpers';
import { useMessage } from '@/composables/useMessage';
import { useExternalHooks } from '@/composables/useExternalHooks';
import { usePinnedData } from '@/composables/usePinnedData';
import { useRouter } from 'vue-router';
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
import { useTelemetry } from '@/composables/useTelemetry';
import { useI18n } from '@/composables/useI18n';
import { storeToRefs } from 'pinia';
Expand All @@ -188,6 +186,7 @@ const emit = defineEmits([
const props = withDefaults(
defineProps<{
workflowObject: Workflow;
readOnly?: boolean;
renaming?: boolean;
isProductionExecutionPreview?: boolean;
Expand All @@ -202,8 +201,6 @@ const externalHooks = useExternalHooks();
const nodeHelpers = useNodeHelpers();
const { activeNode } = storeToRefs(ndvStore);
const pinnedData = usePinnedData(activeNode);
const router = useRouter();
const workflowHelpers = useWorkflowHelpers({ router });
const workflowActivate = useWorkflowActivate();
const nodeTypesStore = useNodeTypesStore();
const uiStore = useUIStore();
Expand Down Expand Up @@ -266,12 +263,12 @@ const workflowRunData = computed(() => {
return null;
});
const workflow = computed(() => workflowHelpers.getCurrentWorkflow());
const parentNodes = computed(() => {
if (activeNode.value) {
return (
workflow.value.getParentNodesByDepth(activeNode.value.name, 1).map(({ name }) => name) || []
props.workflowObject
.getParentNodesByDepth(activeNode.value.name, 1)
.map(({ name }) => name) || []
);
} else {
return [];
Expand Down Expand Up @@ -374,13 +371,17 @@ const maxInputRun = computed(() => {
return 0;
}
const workflowNode = workflow.value.getNode(activeNode.value.name);
const workflowNode = props.workflowObject.getNode(activeNode.value.name);
if (!workflowNode || !activeNodeType.value) {
return 0;
}
const outputs = NodeHelpers.getNodeOutputs(workflow.value, workflowNode, activeNodeType.value);
const outputs = NodeHelpers.getNodeOutputs(
props.workflowObject,
workflowNode,
activeNodeType.value,
);
let node = inputNode.value;
Expand Down Expand Up @@ -729,11 +730,7 @@ watch(
}
void externalHooks.run('dataDisplay.nodeTypeChanged', {
nodeSubtitle: nodeHelpers.getNodeSubtitle(
node,
activeNodeType.value,
workflowHelpers.getCurrentWorkflow(),
),
nodeSubtitle: nodeHelpers.getNodeSubtitle(node, activeNodeType.value, props.workflowObject),
});
setTimeout(() => {
Expand Down
35 changes: 19 additions & 16 deletions packages/editor-ui/src/components/__tests__/NodeDetailsView.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,9 @@ async function createPiniaWithActiveNode() {
await useSettingsStore().getSettings();
await useUsersStore().loginWithCookie();

return pinia;
return { pinia, currentWorkflow: workflowsStore.getCurrentWorkflow() };
}

const renderComponent = createComponentRenderer(NodeDetailsView, {
props: {
teleported: false,
appendToBody: false,
},
global: {
mocks: {
$route: {
name: VIEWS.WORKFLOW,
},
},
},
});

describe('NodeDetailsView', () => {
let server: ReturnType<typeof setupServer>;

Expand All @@ -70,8 +56,25 @@ describe('NodeDetailsView', () => {
});

it('should render correctly', async () => {
const { pinia, currentWorkflow } = await createPiniaWithActiveNode();

const renderComponent = createComponentRenderer(NodeDetailsView, {
props: {
teleported: false,
appendToBody: false,
workflowObject: currentWorkflow,
},
global: {
mocks: {
$route: {
name: VIEWS.WORKFLOW,
},
},
},
});

const wrapper = renderComponent({
pinia: await createPiniaWithActiveNode(),
pinia,
});

await waitFor(() =>
Expand Down
22 changes: 21 additions & 1 deletion packages/editor-ui/src/stores/workflows.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,23 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
};
}

function updateCachedWorkflow() {
const nodeTypes = getNodeTypes();
const nodes = getNodes();
const connections = allConnections.value;

cachedWorkflow = new Workflow({
id: workflowId.value,
name: workflowName.value,
nodes,
connections,
active: false,
nodeTypes,
settings: workflowSettings.value,
pinData: pinnedWorkflowData.value,
});
}

function getWorkflow(nodes: INodeUi[], connections: IConnections, copyData?: boolean): Workflow {
const nodeTypes = getNodeTypes();
let cachedWorkflowId: string | undefined = workflowId.value;
Expand All @@ -362,7 +379,7 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
function getCurrentWorkflow(copyData?: boolean): Workflow {
const nodes = getNodes();
const connections = allConnections.value;
const cacheKey = JSON.stringify({ nodes, connections, pinData: pinnedWorkflowData.value });
const cacheKey = JSON.stringify({ nodes, connections });
if (!copyData && cachedWorkflow && cacheKey === cachedWorkflowKey) {
return cachedWorkflow;
}
Expand Down Expand Up @@ -641,6 +658,7 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
...workflow.value,
pinData: pinData || {},
};
updateCachedWorkflow();

dataPinningEventBus.emit('pin-data', pinData || {});
}
Expand Down Expand Up @@ -711,6 +729,7 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
};

uiStore.stateIsDirty = true;
updateCachedWorkflow();

dataPinningEventBus.emit('pin-data', { [payload.node.name]: storedPinData });
}
Expand All @@ -727,6 +746,7 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
};

uiStore.stateIsDirty = true;
updateCachedWorkflow();

dataPinningEventBus.emit('unpin-data', { [payload.node.name]: undefined });
}
Expand Down
1 change: 1 addition & 0 deletions packages/editor-ui/src/views/NodeView.v2.vue
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,7 @@ onBeforeUnmount(() => {
</Suspense>
<Suspense>
<NodeDetailsView
:workflow-object="editableWorkflowObject"
:read-only="isReadOnlyRoute || isReadOnlyEnvironment"
:is-production-execution-preview="isProductionExecutionPreview"
:renaming="false"
Expand Down
1 change: 1 addition & 0 deletions packages/editor-ui/src/views/NodeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
</div>
</div>
<NodeDetailsView
:workflow-object="currentWorkflowObject"
:read-only="isReadOnlyRoute || readOnlyEnv"
:renaming="renamingActive"
:is-production-execution-preview="isProductionExecutionPreview"
Expand Down

0 comments on commit 13d83f2

Please sign in to comment.