mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-10 06:34:05 -08:00
perf(editor): Improve node rendering performance when opening large workflows (#7904)
## Summary In an effort to do as little processing as possible in each `Node` component, this PR passes current workflow object to it as a property instead of calling the slow `getCurrentWorkflow` store getter a few times in each node. This should substantially improve loading times for large workflows. As a benchmark, I was using a workflow from [this Linear ticket](https://linear.app/n8n/issue/ADO-1501/deliveryhero-enterprise-instance-very-slow-loading-workflows) and this fix brought down opening time by **20 seconds**. Together with fixes from #7901, this workflow was opening in less than **10 seconds** on my laptop. [Latest e2e run](https://github.com/n8n-io/n8n/actions/runs/7062162739) #### How to test the change: 1. Open a large workflow 2. Observe loading time ## Issues fixed ADO-1523 https://community.n8n.io/t/ui-very-slow-with-more-than-100-nodes/8236/14 ## Review / Merge checklist - [x] PR title and summary are descriptive. **Remember, the title automatically goes into the changelog. Use `(no-changelog)` otherwise.** ([conventions](https://github.com/n8n-io/n8n/blob/master/.github/pull_request_title_conventions.md)) - [ ] [Docs updated](https://github.com/n8n-io/n8n-docs) or follow-up ticket created. - [ ] Tests included. > A bug is not considered fixed, unless a test is added to prevent it from happening again. A feature is not complete without tests. > > *(internal)* You can use Slack commands to trigger [e2e tests](https://www.notion.so/n8n/How-to-use-Test-Instances-d65f49dfc51f441ea44367fb6f67eb0a?pvs=4#a39f9e5ba64a48b58a71d81c837e8227) or [deploy test instance](https://www.notion.so/n8n/How-to-use-Test-Instances-d65f49dfc51f441ea44367fb6f67eb0a?pvs=4#f6a177d32bde4b57ae2da0b8e454bfce) or [deploy early access version on Cloud](https://www.notion.so/n8n/Cloudbot-3dbe779836004972b7057bc989526998?pvs=4#fef2d36ab02247e1a0f65a74f6fb534e).
This commit is contained in:
parent
403ba6e9ca
commit
a8049a0def
|
@ -286,15 +286,11 @@ export default defineComponent({
|
||||||
return this.data.type === MANUAL_TRIGGER_NODE_TYPE;
|
return this.data.type === MANUAL_TRIGGER_NODE_TYPE;
|
||||||
},
|
},
|
||||||
isConfigNode(): boolean {
|
isConfigNode(): boolean {
|
||||||
return this.nodeTypesStore.isConfigNode(
|
return this.nodeTypesStore.isConfigNode(this.workflow, this.data, this.data?.type ?? '');
|
||||||
this.getCurrentWorkflow(),
|
|
||||||
this.data,
|
|
||||||
this.data?.type ?? '',
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
isConfigurableNode(): boolean {
|
isConfigurableNode(): boolean {
|
||||||
return this.nodeTypesStore.isConfigurableNode(
|
return this.nodeTypesStore.isConfigurableNode(
|
||||||
this.getCurrentWorkflow(),
|
this.workflow,
|
||||||
this.data,
|
this.data,
|
||||||
this.data?.type ?? '',
|
this.data?.type ?? '',
|
||||||
);
|
);
|
||||||
|
@ -349,9 +345,8 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.node && this.nodeType) {
|
if (this.node && this.nodeType) {
|
||||||
const workflow = this.workflowsStore.getCurrentWorkflow();
|
|
||||||
const inputs =
|
const inputs =
|
||||||
NodeHelpers.getNodeInputs(workflow, this.node, this.nodeType) ||
|
NodeHelpers.getNodeInputs(this.workflow, this.node, this.nodeType) ||
|
||||||
([] as Array<ConnectionTypes | INodeInputConfiguration>);
|
([] as Array<ConnectionTypes | INodeInputConfiguration>);
|
||||||
const inputTypes = NodeHelpers.getConnectionTypes(inputs);
|
const inputTypes = NodeHelpers.getConnectionTypes(inputs);
|
||||||
|
|
||||||
|
@ -372,7 +367,7 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
const outputs =
|
const outputs =
|
||||||
NodeHelpers.getNodeOutputs(workflow, this.node, this.nodeType) ||
|
NodeHelpers.getNodeOutputs(this.workflow, this.node, this.nodeType) ||
|
||||||
([] as Array<ConnectionTypes | INodeOutputConfiguration>);
|
([] as Array<ConnectionTypes | INodeOutputConfiguration>);
|
||||||
|
|
||||||
const outputTypes = NodeHelpers.getConnectionTypes(outputs);
|
const outputTypes = NodeHelpers.getConnectionTypes(outputs);
|
||||||
|
@ -634,8 +629,7 @@ export default defineComponent({
|
||||||
// and ends up bogging down the UI with big workflows, for example when pasting a workflow or even opening a node...
|
// and ends up bogging down the UI with big workflows, for example when pasting a workflow or even opening a node...
|
||||||
// so we only update it when necessary (when node is mounted and when it's opened and closed (isActive))
|
// so we only update it when necessary (when node is mounted and when it's opened and closed (isActive))
|
||||||
try {
|
try {
|
||||||
const nodeSubtitle =
|
const nodeSubtitle = this.getNodeSubtitle(this.data, this.nodeType, this.workflow) || '';
|
||||||
this.getNodeSubtitle(this.data, this.nodeType, this.getCurrentWorkflow()) || '';
|
|
||||||
|
|
||||||
this.nodeSubtitle = nodeSubtitle.includes(CUSTOM_API_CALL_KEY) ? '' : nodeSubtitle;
|
this.nodeSubtitle = nodeSubtitle.includes(CUSTOM_API_CALL_KEY) ? '' : nodeSubtitle;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -17,6 +17,7 @@ import type {
|
||||||
INodeInputConfiguration,
|
INodeInputConfiguration,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
INodeOutputConfiguration,
|
INodeOutputConfiguration,
|
||||||
|
Workflow,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { useUIStore } from '@/stores/ui.store';
|
import { useUIStore } from '@/stores/ui.store';
|
||||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||||
|
@ -104,6 +105,10 @@ export const nodeBase = defineComponent({
|
||||||
showCustomTooltip: {
|
showCustomTooltip: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
},
|
},
|
||||||
|
workflow: {
|
||||||
|
type: Object as () => Workflow,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
__addEndpointTestingData(endpoint: Endpoint, type: string, inputIndex: number) {
|
__addEndpointTestingData(endpoint: Endpoint, type: string, inputIndex: number) {
|
||||||
|
@ -123,9 +128,8 @@ export const nodeBase = defineComponent({
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
const workflow = this.workflowsStore.getCurrentWorkflow();
|
|
||||||
const inputs: Array<ConnectionTypes | INodeInputConfiguration> =
|
const inputs: Array<ConnectionTypes | INodeInputConfiguration> =
|
||||||
NodeHelpers.getNodeInputs(workflow, this.data!, nodeTypeData) || [];
|
NodeHelpers.getNodeInputs(this.workflow, this.data!, nodeTypeData) || [];
|
||||||
this.inputs = inputs;
|
this.inputs = inputs;
|
||||||
|
|
||||||
const sortedInputs = [...inputs];
|
const sortedInputs = [...inputs];
|
||||||
|
@ -338,8 +342,7 @@ export const nodeBase = defineComponent({
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
const workflow = this.workflowsStore.getCurrentWorkflow();
|
this.outputs = NodeHelpers.getNodeOutputs(this.workflow, this.data, nodeTypeData) || [];
|
||||||
this.outputs = NodeHelpers.getNodeOutputs(workflow, this.data, nodeTypeData) || [];
|
|
||||||
|
|
||||||
// TODO: There are still a lot of references of "main" in NodesView and
|
// TODO: There are still a lot of references of "main" in NodesView and
|
||||||
// other locations. So assume there will be more problems
|
// other locations. So assume there will be more problems
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
:isActive="!!activeNode && activeNode.name === nodeData.name"
|
:isActive="!!activeNode && activeNode.name === nodeData.name"
|
||||||
:hideActions="pullConnActive"
|
:hideActions="pullConnActive"
|
||||||
:isProductionExecutionPreview="isProductionExecutionPreview"
|
:isProductionExecutionPreview="isProductionExecutionPreview"
|
||||||
|
:workflow="currentWorkflowObject"
|
||||||
>
|
>
|
||||||
<template #custom-tooltip>
|
<template #custom-tooltip>
|
||||||
<span
|
<span
|
||||||
|
@ -691,6 +692,9 @@ export default defineComponent({
|
||||||
instance(): BrowserJsPlumbInstance {
|
instance(): BrowserJsPlumbInstance {
|
||||||
return this.canvasStore.jsPlumbInstance;
|
return this.canvasStore.jsPlumbInstance;
|
||||||
},
|
},
|
||||||
|
currentWorkflowObject(): Workflow {
|
||||||
|
return this.workflowsStore.getCurrentWorkflow();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Reference in a new issue