Skip to content

Commit

Permalink
perf(editor): Improve performance when opening large workflows with n…
Browse files Browse the repository at this point in the history
…ode issues (#7901)

This PR should improve performance when opening large workflows that
contain node issues (Fixes ADO-1521)

**Background**
Main reason for this poor performance is that our `getCurrentWorkflow()`
store getter is unnecessarily heavy but on top of that we are calling it
more than we need. This addresses the second part of the issue by
changing the following:
- Pausing node issue processing while workflows are loading
- Only getting current workflow once (instead for every node) when
calling `refreshNodeIssues`

**Benchmark**
This was tested on a workflow attached to [this Linear
ticket](https://linear.app/n8n/issue/ADO-1501/deliveryhero-enterprise-instance-very-slow-loading-workflows)
and this fix brings down opening time from **~1m10s** to **~28s** on my
laptop.

**Tests**
- [Latest e2e tests
run](https://github.com/n8n-io/n8n/actions/runs/7060874994)

https://community.n8n.io/t/ui-very-slow-with-more-than-100-nodes/8236/14
  • Loading branch information
MiloradFilipovic authored Dec 4, 2023
1 parent 132d691 commit 4bd7ae2
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 9 deletions.
1 change: 1 addition & 0 deletions cypress/e2e/28-debug.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ describe('Debug', () => {
cy.url().should('not.include', '/debug');

workflowPage.actions.executeWorkflow();
workflowPage.actions.zoomToFit();
workflowPage.actions.deleteNode(IF_NODE_NAME);

executionsTab.actions.switchToExecutionsTab();
Expand Down
5 changes: 3 additions & 2 deletions packages/editor-ui/src/mixins/nodeHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export const nodeHelpers = defineComponent({
// Updates all the issues on all the nodes
refreshNodeIssues(): void {
const nodes = this.workflowsStore.allNodes;
const workflow = this.workflowsStore.getCurrentWorkflow();
let nodeType: INodeTypeDescription | null;
let foundNodeIssues: INodeIssues | null;

Expand All @@ -99,7 +100,7 @@ export const nodeHelpers = defineComponent({
return;
}
nodeType = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
foundNodeIssues = this.getNodeIssues(nodeType, node);
foundNodeIssues = this.getNodeIssues(nodeType, node, workflow);
if (foundNodeIssues !== null) {
node.issues = foundNodeIssues;
}
Expand All @@ -110,6 +111,7 @@ export const nodeHelpers = defineComponent({
getNodeIssues(
nodeType: INodeTypeDescription | null,
node: INodeUi,
workflow: Workflow,
ignoreIssues?: string[],
): INodeIssues | null {
const pinDataNodeNames = Object.keys(this.workflowsStore.getPinData || {});
Expand Down Expand Up @@ -147,7 +149,6 @@ export const nodeHelpers = defineComponent({
}
}

const workflow = this.workflowsStore.getCurrentWorkflow();
const nodeInputIssues = this.getNodeInputIssues(workflow, node, nodeType);
if (nodeIssues === null) {
nodeIssues = nodeInputIssues;
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/mixins/workflowHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ export const workflowHelpers = defineComponent({
typeUnknown: true,
};
} else {
nodeIssues = this.getNodeIssues(nodeType.description, node, ['execution']);
nodeIssues = this.getNodeIssues(nodeType.description, node, workflow, ['execution']);
}

if (nodeIssues !== null) {
Expand Down
17 changes: 11 additions & 6 deletions packages/editor-ui/src/views/NodeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,9 @@ export default defineComponent({
instance(): BrowserJsPlumbInstance {
return this.canvasStore.jsPlumbInstance;
},
isLoading(): boolean {
return this.loadingService !== null;
},
currentWorkflowObject(): Workflow {
return this.workflowsStore.getCurrentWorkflow();
},
Expand Down Expand Up @@ -2697,10 +2700,6 @@ export default defineComponent({
this.dropPrevented = true;
this.workflowsStore.addConnection({ connection: connectionData });
this.uiStore.stateIsDirty = true;
if (!this.suspendRecordingDetachedConnections) {
this.historyStore.pushCommandToUndo(new AddConnectionCommand(connectionData));
}
if (!this.isReadOnlyRoute && !this.readOnlyEnv) {
NodeViewUtils.hideOutputNameLabel(info.sourceEndpoint);
Expand Down Expand Up @@ -2742,8 +2741,14 @@ export default defineComponent({
}
}
this.dropPrevented = false;
this.updateNodesInputIssues();
this.resetEndpointsErrors();
if (!this.isLoading) {
this.uiStore.stateIsDirty = true;
if (!this.suspendRecordingDetachedConnections) {
this.historyStore.pushCommandToUndo(new AddConnectionCommand(connectionData));
}
this.updateNodesInputIssues();
this.resetEndpointsErrors();
}
} catch (e) {
console.error(e);
}
Expand Down

0 comments on commit 4bd7ae2

Please sign in to comment.