ant-design / ant-design

An enterprise-class UI design language and React UI library
https://ant.design
MIT License
92.36k stars 49.58k forks source link

table/select/checkbox 数据多 选中响应慢 #10431

Closed Tuerping closed 4 years ago

Tuerping commented 6 years ago

Version

3.5.0

Environment

react 16.2.0; antd 3.4.3

Reproduction link

https://github.com/Tuerping/testTableCheckbox

Steps to reproduce

在tableList 页面中 当pageSize 为10 时 点击checkbox 反应速度正常; 当pageSize为200时,点击checkbox反应速度变慢

What is expected?

checkbox点击反应速度和 pageSize数据量 与 columns数量 无关

What is actually happening?

当pageSize或者columns 增多,checkbox点击反应速度会变慢

ant-design-bot commented 6 years ago

Translation of this issue:


table checkbox More data selected response slow

Version

3.5.0

Environment

React 16.2.0; antd 3.4.3

Reproduction link

[https://github.com/Tuerping/testTableCheckbox] (https://github.com/Tuerping/testTableCheckbox)

Steps to reproduce

On the tableList page When the pageSize is 10 Click the checkbox The response speed is normal; When the pageSize is 200, click the checkbox to slow down the response

What is expected?

The checkbox click response speed and pageSize data amount are independent of the number of columns

What is actually happening?

When pageSize or columns increase, checkbox click response slows

QzAmoy commented 6 years ago

这个问题我也遇到了,数据量大的时候,不止勾选响应慢,甚至会影响其他组件的响应速度。不知道你是否有找到解决方法?

Tuerping commented 6 years ago

没有找到办法,没人回答我的问题;你有解决出来吗?

QzAmoy commented 6 years ago

没有啊,试过删除动画,没什么效果。我看你发了听多次这个问题,都被关掉了。

Tuerping commented 6 years ago

自己写checkbox进去吧,自己写事件

ant-design-bot commented 6 years ago

Hello @Tuerping. Please provide a online reproduction by forking this link https://u.ant.design/codesandbox-repro. Issues labeled by Need Reproduce will be closed if no activities in 7 days.

afc163 commented 6 years ago

Issues labeled by Need Reproduce will be closed if no activities in 7 days.

@yesmeck seems not working

ant-design-bot commented 6 years ago

This issue is closed because it has been marked as Need Reproduce, but has not had recent activity. If you can provide a reproduce, feel free to ping anyone of our maintainers to reopen this issue. Thank you for your contributions.

fgiarritiello commented 5 years ago

Can we please reopen this? Here is a link to reproduce the problem

https://codepen.io/anon/pen/QYdWaE?&editable=true&editors=001

When the table has many rows rendered the UI becomes really laggy and the page is just slow and unusable.

galbash commented 5 years ago

I am experiencing the same problem :( I think the reason is that all of the cells are re-rendered even though only the selection changed. Is there any way around this? I tried returning a custom ReactNode from the render function of the columns property that overrides shouldComponentUpdate, but I think since the function is called each time the table is rendered, I end up getting different components each time and they are rendered anyway. thoughts?

fgiarritiello commented 5 years ago

yeah, I would expect that when a row is selected or expanded only that row should be re-rendered. Instead the whole table is re-rendered and it gets pretty much unusable when you have a big set of data. This is becoming a show stopper for my company.

UnicornXU commented 5 years ago

最后这个问题解决了么?我也遇到了这个问题

ztplz commented 5 years ago

感觉我可以挑战一下

lttien1 commented 5 years ago

@ant-design-bot

How about this issue?

songyule commented 5 years ago

我用了分页,每页十条,datasource.length = 10000 的时候点分页就很卡

Jonarzz commented 5 years ago

This is a very important issue for my company as well. Any updates?

tsahnar commented 5 years ago

Also encountering this issue. Has anybody managed to have good performance with multiple selection and a lot of rows?

DeadManPoe commented 5 years ago

Experiencing the same issue for my company too.

mqliutie commented 5 years ago

我解决的办法是将Checkbox拆分成独立组件, 有自己的state

Checkbox onchange的时候调用父组件的onChange

父组件的onChange不做setState, 而是更新 this.checkedList

indeterminate 不等于更新后的 indeterminate 的时候forceUpdate 因为这个时候父组件要更新自己的全选状态,其他时候让Checkbox组件自己玩`

Checkbox组件在componentWillReceiveProps判断组件自身状态是否需要更新

这样只有在全选和非全选切换的时候才出现一下卡顿

下面是我的Checkbox 组件

export default class MyCheckBox extends Component {
    static displayName = 'MyCheckBox';

    constructor(props) {
        super(props);
        this.state = {
            checked: false
        };
    }

    static getDerivedStateFromProps(props, state) {
        if (props.isSelectAll) {
            return {
                checked: true
            };
        }
        if (!props.isSelectAll && !props.indeterminate) {
            return {
                checked: false
            };
        }
        return null;
    }

    render() {
        return (
            <Checkbox
                checked={this.state.checked}
                onChange={() => {
                    this.setState(state => ({
                        checked: !state.checked
                    }));
                    this.props.onChange();
                }}
                disabled={this.props.disabled}
            />
        );
    }
}
AndreSteynPersonal commented 5 years ago

any working solutions yet?

WrathZA commented 5 years ago

I'm also facing this issue.

sebas-deedee commented 5 years ago

Any update on this issue?

ksh033 commented 5 years ago

@afc163 这问题有没有的解决办法,包括排序也会很慢..4.0版本好像也没解决这问题的计划

chrisbchrist commented 5 years ago

I know you guys work hard, but this is a really big problem for enterprise applications that can have tens of thousands of rows, essentially rendering the library useless for managing data. Has anyone found a workaround for this that doesn't involve forking AntD and rewriting the component from scratch? We've been using AntD and invested a lot of time in developing our own CRUD wrapper for this table, but it looks like we're going to have to start over with something else.

13luck commented 5 years ago

@chrisbchrist, use ag-grid for real big dataset.

rashmimh commented 5 years ago

I am facing this issue for select multiple.

[Violation] 'animationend' handler took 14997ms
[Violation] 'animationend' handler took 15072ms
Forced reflow while executing JavaScript took <N>ms
[Violation] 'click' handler took 575ms
[Violation] 'click' handler took 320ms
[Violation] 'setTimeout' handler took 54ms . 
[Violation] 'animationend' handler took 15229ms
[Violation] 'animationend' handler took 15290ms
[Violation] 'click' handler took 191ms
prashanth726 commented 4 years ago

Any update!>

WJB3 commented 4 years ago

数据量很大,每当选择每一行时,时间间隔时间较长

WJB3 commented 4 years ago

数据量很大,每当选择每一行时,时间间隔时间较长,希望有人能给个官方解决方案

prashanth726 commented 4 years ago

@Tuerping are you able to solve this?

mfaradzh commented 4 years ago

@mqliutie

My solution was to Checkboxsplit it into separate components , with my ownstate

Checkbox onchangeWhen calling the parent componentonChange

The parent component onChangedoes not do setState, but updatesthis.checkedList

When indeterminatethe update is not equal to the indeterminatetime forceUpdatebecause this time the father of the components to update its full-selected state, at other times so that Checkboxthe components they play `

CheckboxThe component is componentWillReceivePropsdetermining whether the component's own status needs to be updated

This will only cause a lag when switching between full and non-selection

Below is my Checkbox component

export default class MyCheckBox extends Component {
    static displayName = 'MyCheckBox';

    constructor(props) {
        super(props);
        this.state = {
            checked: false
        };
    }

    static getDerivedStateFromProps(props, state) {
        if (props.isSelectAll) {
            return {
                checked: true
            };
        }
        if (!props.isSelectAll && !props.indeterminate) {
            return {
                checked: false
            };
        }
        return null;
    }

    render() {
        return (
            <Checkbox
                checked={this.state.checked}
                onChange={() => {
                    this.setState(state => ({
                        checked: !state.checked
                    }));
                    this.props.onChange();
                }}
                disabled={this.props.disabled}
            />
        );
    }
}

Could you please provide an example of how you attached it? Thank you

see365 commented 4 years ago

200条就卡了 性能好差啊

mqliutie commented 4 years ago

@mqliutie

My solution was to Checkboxsplit it into separate components , with my ownstate Checkbox onchangeWhen calling the parent componentonChange The parent component onChangedoes not do setState, but updatesthis.checkedList When indeterminatethe update is not equal to the indeterminatetime forceUpdatebecause this time the father of the components to update its full-selected state, at other times so that Checkboxthe components they play CheckboxThe component iscomponentWillReceiveProps`determining whether the component's own status needs to be updated This will only cause a lag when switching between full and non-selection Below is my Checkbox component

export default class MyCheckBox extends Component {
    static displayName = 'MyCheckBox';

    constructor(props) {
        super(props);
        this.state = {
            checked: false
        };
    }

    static getDerivedStateFromProps(props, state) {
        if (props.isSelectAll) {
            return {
                checked: true
            };
        }
        if (!props.isSelectAll && !props.indeterminate) {
            return {
                checked: false
            };
        }
        return null;
    }

    render() {
        return (
            <Checkbox
                checked={this.state.checked}
                onChange={() => {
                    this.setState(state => ({
                        checked: !state.checked
                    }));
                    this.props.onChange();
                }}
                disabled={this.props.disabled}
            />
        );
    }
}

Could you please provide an example of how you attached it? Thank you

For convenience, I imported the lodash library

import React, { Component } from 'react';
import { Table, Checkbox, Button, Modal } from 'antd';
import _ from 'lodash';

export default class Parent extends Component {
    static displayName = 'Parent';

    constructor(props) {
        super(props);
        this.checkedList = [];
        this.state = {
            data: [{
                id: 1,
                name: 'Lucky'
            }, {
                id: 2,
                name: 'Lily'
            }, {
                id: 3,
                name: 'Jim'
            }],
            columns: [{
                title: () => <Checkbox onChange={e => {
                    if (e.target.checked) {
                        this.selectedAll = true;
                        this.indeterminate = false;
                        this.checkedList = this.state.data;
                        return this.forceUpdate();
                    }
                    this.selectedAll = false;
                    this.indeterminate = false;
                    this.checkedList = [];
                    this.forceUpdate();

                }} checked={this.selectedAll} indeterminate={this.indeterminate}/>,
                key: 'checkbox',
                render: (row) => {
                    return <ChildCheckbox name={row.name} isSelectAll={this.selectedAll} indeterminate={this.indeterminate} onChange={() => {
                        // init values ;
                        this.selectedAll = false;
                        this.indeterminate = true;
                        const originLength = this.checkedList.length;
                        // remove will change checkedList
                        const removedRow = _.remove(this.checkedList, r => r.id === row.id);
                        if (_.isEmpty(removedRow)) {
                            // if removedRow is empty that means the row is not in checkedList
                            // if removedRow is not empty the row was removed from checkedList
                            this.checkedList.push(row);
                        }

                        // now all row is checked so should forceUpdate
                        if (this.checkedList.length === this.state.data.length) {
                            this.selectedAll = true;
                            this.indeterminate = false;
                            // should update selectedAll status
                            this.forceUpdate();
                        }

                        // now all row is not checked so should forceUpdate
                        if (this.checkedList.length === 0) {
                            this.selectedAll = false;
                            // I know that row all is checked or all is not checked.
                            this.indeterminate = false;
                            this.forceUpdate();
                        }

                        // from none to one or from all checkedRows to checkedRows.length - 1, status should be changed
                        if (originLength === 0 || originLength === this.state.data.length) {
                            this.indeterminate = true;
                            this.forceUpdate();
                        }

                    }}/>;
                }
            }, {
                title: 'name',
                dataIndex: 'name',
            }]
        };
    }

    render() {
        return (
            <React.Fragment>
                <Button
                    style={{ marginBottom: 16 }}
                    onClick={() => Modal.info({ title: `Your checkedList value is ${JSON.stringify(this.checkedList, null, 4)}` })}
                >
                    get checkedList</Button>
                <Table bordered columns={this.state.columns} rowKey='id' dataSource={this.state.data}/>
            </React.Fragment>
        );
    }

}

class ChildCheckbox extends React.PureComponent {
    static displayName = 'ChildCheckbox';

    state = {
        checked: false
    };

    static defaultProps = {
        isSelectAll: false,
        indeterminate: false
    };

    static getDerivedStateFromProps(props, state) {
        if (props.isSelectAll) {
            return {
                checked: true
            };
        }
        if (!props.isSelectAll && !props.indeterminate) {
            return {
                checked: false
            };
        }
        return null;
    }

    render() {
        console.log(`name : ${this.props.name} Checkbox render`);
        return (
            <Checkbox
                checked={this.state.checked}
                onChange={() => {
                    this.setState(state => ({
                        checked: !state.checked
                    }));
                    this.props.onChange();
                }}
                disabled={this.props.disabled}
            />
        );
    }
}

You can open the chrome dev tool, the console will be logged when toggle select all status

huangfei7528 commented 4 years ago

这个问题这么久了 请问有解决方案了么

running-snail-sfs commented 4 years ago

这么大的问题,官方也不出来给个方案,主要是性能太差了,200条就卡成那样了

yoyo837 commented 4 years ago

3.x工作安排性能的优先级不高,4.0已经在着手解决,你也可以考虑提交相关PR帮助推进。

running-snail-sfs commented 4 years ago

好的,希望这个性能问题尽快完善,因为如果基于现有业务更换组件,代价太大,也不利于后期维护

------------------ 原始邮件 ------------------ 发件人: "Amumu"<notifications@github.com>; 发送时间: 2019年12月18日(星期三) 上午10:33 收件人: "ant-design/ant-design"<ant-design@noreply.github.com>; 抄送: "742410510"<742410510@qq.com>;"Comment"<comment@noreply.github.com>; 主题: Re: [ant-design/ant-design] table/select/checkbox 数据多 选中响应慢 (#10431)

3.x工作安排性能的优先不高,4.0已经在着手解决,你也可以考虑提交相关PR帮助推进。

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

hsluoyz commented 4 years ago

We are also using it in our project. Can we fix it maybe a little sooner?

prashanth726 commented 4 years ago

Please check https://next.ant.design/ . V4.0 ant design fixed the issue hopefully.

hsluoyz commented 4 years ago

@prashanth726 did v4.0 fix this issue?

prashanth726 commented 4 years ago

@hsluoyz I haven't tested in production. But in 4.0 they support virtual list - https://next.ant.design/components/table/#components-table-demo-virtual-list

And I tried the same on codesandbox environment with filter, sort & checkbox - it worked perfectly.

NICK-DUAN commented 4 years ago

Select也会有这个问题

furkanilhan commented 4 years ago

@hsluoyz I haven't tested in production. But in 4.0 they support virtual list - https://next.ant.design/components/table/#components-table-demo-virtual-list

And I tried the same on codesandbox environment with filter, sort & checkbox - it worked perfectly.

@prashanth726 How did you implement the row selection in virtual list? Can you exlain?

afc163 commented 4 years ago

Perfermance issue had been resolved in favor of our visual list solution in v4: https://github.com/ant-design/ant-design/issues/21656

chillyistkult commented 4 years ago

@afc163 There is no "visual list" mentioned on the issue you linked. I don't see the performance issue solved in latest 4.0.2 for a normal table with a couple thousand rows.

DeadManPoe commented 4 years ago

@chillyistkult I think @afc163 meant to say "virtual list". Anyways, I don't think the virtual list solution solves the problem completely: I believe the problem is that the table does a whole re-render every time a checkbox is checked.

lorenzocestaro commented 4 years ago

@DeadManPoe If the table is virtualized properly the component should render again only the rows currently in view.

DeadManPoe commented 4 years ago

@lorenzocestaro Sure, still all the rows that are currently visible will be re-rendered. The problem is that only the selected row should be re-rendered rather than all the others, regardless of the use of virtualization

lorenzocestaro commented 4 years ago

Sure I completely get your point and agree. What I meant to say is you can mitigate for now by controlling how many rows are visible and manage performance. Of course it would be much better if only the affected row was rerendered.

running-snail-sfs commented 4 years ago

不知道这个虚拟表格能不能也优化到3.x,因为很多的项目考虑到兼容性和业务升级的一系列问题,不准备升级4,0,这就很尴尬