Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

选中大量节点时性能差 #1325

Open
OpportunityLiu opened this issue Sep 8, 2021 · 17 comments · Fixed by #1393 · May be fixed by #4201
Open

选中大量节点时性能差 #1325

OpportunityLiu opened this issue Sep 8, 2021 · 17 comments · Fixed by #1393 · May be fixed by #4201
Assignees
Labels
bug:selection selection plugin bug v2.0 will fix in v2.0

Comments

@OpportunityLiu
Copy link
Contributor

Expected Behavior

多选时仅更新一次

Current Behavior

image

this.updateContainer()

this.updateContainer()

多选时更新多次

Possible Solution

Steps To Reproduce

  1. 创建大量节点
  2. 全选节点
Error Message & Stack Trace

<!-- Provide a log message if relevant -->

Additional Context

Your Environment

  • x6: 1.26.1
  • OS: [e.g. macOS Sierra 10.12.3]
  • Browser: [e.g. chrome 78.0.3904.108]
@OpportunityLiu OpportunityLiu added the type: bug 缺陷 Defects and unexpected behaviors label Sep 8, 2021
@OpportunityLiu
Copy link
Contributor Author

OpportunityLiu commented Sep 9, 2021

目前使用的 fix:

const updateContainer = Selection.prototype.updateContainer;

Selection.prototype.updateContainer = function () {
    if (this.updateContainerId) {
        cancelAnimationFrame(this.updateContainerId);
        this.updateContainerId = undefined;
    }

    this.updateContainerId = requestAnimationFrame(() => {
        this.updateContainerId = undefined;
        updateContainer.call(this);
    });
};

但是拖动的性能还是很差,用了 pointerEvents: 'none' 以后 following: false 就不起作用了

@drl990114
Copy link
Contributor

drl990114 commented Sep 23, 2021

I set the following settings in the graph, so that the dragging will not perform the full rendering of the component, but this seems to prevent the mouse events from being passed to the component.

If you don't need a lot of interaction between components, this may solve part of the performance problem. But this is obviously not a good solution. I also hope that someone can provide a better solution.

selecting: {
        showNodeSelectionBox: true,
        following: false
}

@OpportunityLiu
Copy link
Contributor Author

OpportunityLiu commented Sep 23, 2021

That's also not working in current version, see #1328

@drl990114
Copy link
Contributor

This seems to be a problem in the new version, there is no such bug in version 1.25.3

@NewByVector NewByVector linked a pull request Oct 1, 2021 that will close this issue
15 tasks
@NewByVector
Copy link
Contributor

  1. x6 优化:框选的时候只有在最后触发一次 updatContainer
  2. 在 selecting 中你开启 useCellGeometry 配置,看下拖动性能是否有改善

@OpportunityLiu
Copy link
Contributor Author

OpportunityLiu commented Oct 2, 2021

其实主要还是 x6-widget-transform 太慢了,一个cell就是10个DOM element,明明设了orth: false 都不打折的(到处都在微操 DOM,这个地方居然用 css 偷懒了)

image

现在我的解决方案是重写 Selection 插件添加选中前通知

import { Collection } from '@antv/x6';
import { Selection } from '@antv/x6/lib/addon/selection';

/** 自定义 selection */
export class CustomSelection extends Selection {
    /** 添加事件 */
    protected override onCollectionUpdated(args: Collection.EventArgs['updated']): void {
        const myArgs = {
            added: args.added,
            removed: args.removed,
            options: args.options,
            selected: this.cells,
        };
        void this.trigger('selection:changing', myArgs);
        void this.graph.trigger('selection:changing', myArgs);
        super.onCollectionUpdated(args);
    }
}

然后在选中过多时把 transform 直接关掉(还有 snapline)

// 优化选中性能
graph.on('selection:changing', () => {
    const l = graph.getSelectedCellCount();
    this.tooManySelection = l > 20;
    graph.container.classList.toggle('hide-selection-box-node', !this.tooManySelection);
    graph.toggleSnapline(l < 2 && !!(command.modifiers & KeyModifier.Shift));
    graph.hideSnapline();
});
resizing: {
    enabled: () => !this.tooManySelection,
}
rotating: {
    enabled: () => !this.tooManySelection,
},

然后拿 x6-widget-selection 画的框当选中框

.hide-selection-box-node .x6-widget-selection-box-node {
  display: none;
}

@OpportunityLiu
Copy link
Contributor Author

OpportunityLiu commented Oct 2, 2021

mxGraph里这个行为是默认的
image
image

@OpportunityLiu
Copy link
Contributor Author

另外,checkView 可以实现 viewport 外的 cell 不渲染(这也是我们从 mxGraph 切换过来的主要原因),但是对选中框啥的就没啥办法了。导致一个节点数多的图形,普通拖动浏览都十分流畅,一按 Ctrl+A 卡1分钟。

@OpportunityLiu
Copy link
Contributor Author

而且你这个 fix 对于编程的大量选中也不生效啊,Ctrl+A 啥的照卡不误
image

@NewByVector
Copy link
Contributor

@OpportunityLiu 老哥稳呀

@wooderpecker
Copy link

多选后拖拉卡顿,我的解决方法是监听到多选后,根据选中的graph.selection.widget.$selectionContainer[0] 生成一个同等长宽,位置的group,然后把节点加到group里面。实现拖拉不卡顿。取消选中的时候再从group中把节点抽取出来放回canvas,然后删掉group。 后续作者是否可以加个配置项,在多选的时候实现这种功能?

@x6-bot x6-bot bot added the stale Issue that may be closed soon due to the original author not responding any more. label Nov 11, 2021
@NewByVector NewByVector removed the stale Issue that may be closed soon due to the original author not responding any more. label Nov 15, 2021
@kiki-oo
Copy link

kiki-oo commented Nov 29, 2021

多选后拖拉卡顿,我的解决方法是监听到多选后,根据选中的graph.selection.widget.$selectionContainer[0] 生成一个同等长宽,位置的group,然后把节点加到group里面。实现拖拉不卡顿。取消选中的时候再从group中把节点抽取出来放回canvas,然后删掉group。 后续作者是否可以加个配置项,在多选的时候实现这种功能?

这么处理渲染selectionView的耗时只用花费一次。但是看performance中layout调用jquery耗时还是100ms,有没有提高方法呀

@x6-bot x6-bot bot added the stale Issue that may be closed soon due to the original author not responding any more. label Dec 20, 2021
@NewByVector NewByVector self-assigned this Jan 9, 2022
@NewByVector NewByVector removed the stale Issue that may be closed soon due to the original author not responding any more. label Feb 10, 2022
@x6-bot x6-bot bot added the stale Issue that may be closed soon due to the original author not responding any more. label Mar 3, 2022
@NewByVector NewByVector removed the stale Issue that may be closed soon due to the original author not responding any more. label Mar 26, 2022
@NewByVector NewByVector added type: feature 新功能 Feature/enhancement requests and removed type: bug 缺陷 Defects and unexpected behaviors labels Mar 26, 2022
@mugo1993-ss
Copy link

另外,checkView 可以实现 viewport 外的 cell 不渲染(这也是我们从 mxGraph 切换过来的主要原因),但是对选中框啥的就没啥办法了。导致一个节点数多的图形,普通拖动浏览都十分流畅,一按 Ctrl+A 卡1分钟。

请问大佬怎么实现,渲染6000个节点和6000条边,界面卡死的问题呢?

@NewByVector NewByVector added the v2.0 will fix in v2.0 label Sep 4, 2022
@NewByVector NewByVector added bug:selection selection plugin bug and removed type: feature 新功能 Feature/enhancement requests labels Jan 29, 2023
@antvis antvis deleted a comment from x6-bot bot Jan 29, 2023
@antvis antvis deleted a comment from x6-bot bot Jan 29, 2023
@antvis antvis deleted a comment from x6-bot bot Jan 29, 2023
@zzjjbbaa
Copy link

zzjjbbaa commented Aug 8, 2023

另外,checkView 可以实现 viewport 外的 cell 不渲染(这也是我们从 mxGraph 切换过来的主要原因),但是对选中框啥的就没啥办法了。导致一个节点数多的图形,普通拖动浏览都十分流畅,一按 Ctrl+A 卡1分钟。

请问大佬怎么实现,渲染6000个节点和6000条边,界面卡死的问题呢?

同问,大量图元的渲染问题,持续关注

@bighhhh
Copy link
Contributor

bighhhh commented Sep 6, 2023

卡顿是因为开启了showNodeSelectionBox配置,然后多选时会每一个node绘制一个x6-widget-selection-box的选中框,而每次拖动都会把这个选中框移除然后重新插入。
showNodeSelectionBox设置为false时性能会提升4-5倍,但是多选不显示最外边大的选择框,这问题就很纠结

@bighhhh
Copy link
Contributor

bighhhh commented Sep 6, 2023

这个地方如果改成showNodeSelectionBox启用后,如果选择一个节点则渲染x6-widget-selection-box框,如果多选则只渲染最外层大框而不渲染每一个节点的选中框,则问题就解决了

@bighhhh
Copy link
Contributor

bighhhh commented Sep 17, 2023

目前有个解决方案,可以使400多个不卡顿https://juejin.cn/post/7278974923682644024

@xiawenqi xiawenqi linked a pull request Feb 14, 2024 that will close this issue
15 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug:selection selection plugin bug v2.0 will fix in v2.0
Projects
None yet
9 participants