ant-design: Do not render the whole table when interacting with a single row

  • I have searched the issues of this repository and believe that this is not a duplicate.

Reproduction link

Edit on CodeSandbox

Steps to reproduce

Add a Table Use the onRow function or turn on rowSelections using rowSelection

What is expected?

Only the rows being interacted with should be re-rendered.

What is actually happening?

Currently the whole table is getting re-rendered This degrades the performance dramatically specially when you have 100’s or 1000’s of records.

Current options - Virtual List Yes you can use virtual list looks like now, but that would probably mean rewriting the table because it is not a small change, the example in docs shows this as a much bigger change and a completely different way to write your tables. It’s not just a prop setting.

Real use cases In some cases we want to show 1000 records per page or more, so that people are able to select more records and perform that action in bulk instead of in smaller sets. Not sure how virtual list affects that. Also we may have extended the table and added custom features. This rendering re-renders all attached components, when really that may not be needed.

Bottom line It does not take away from the fact that NOT all rows should be re-rendered when only one row changes

Environment Info
antd 4.2.0
React 16.13
System Mac OSX
Browser Safari 13.1, Chrome 80.0

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 17
  • Comments: 37 (13 by maintainers)

Most upvoted comments

I will be Blunt. @zombieJ the example you provided is buggy, I think we are more in a hurry to close issues than to actually address the core problems. In the example you provided when you toggle rows one after another you see a vey buggy behavior since it seems to select unselect other rows also.

We also are undermining the fact that the table has to be designed from a perspective of performance, simply stating that

Table can not tell what will use in column render function, it always need fully render by default:

points to the fact that we are not open to critical suggestions or feedback. Not rendering a whole table on row change is something that should have been part of the design from start. It will be great if Ant team acknowledges that and tries to rectify it rather than brush it under the carpet and keep closing these issues saying this is how it was designed by default.

I’ve been following this issue for a good while. I’m working on a product based mainly on a table and I did not like the fact that all rows rendered each time selected a row. I must say though that the issue is indeed solved. In my specific case, since all the cells in my table display read-only static data, I just added to all column properties shouldCellUpdate: () => false. In this way, when you interact with a row (i.e. select it in my case) the table does not rerender.

@yeomann, you can’t expect no renders when you change pagination. You are changing your view to see the next batch of rows, of course they need to be rendered. And if you go back to the previous page the rows still need to be rendered, they were unmounted from the DOM and now need to be drawn again. Even using the virtualized table you cannot expect to not have renders, even more so in this case. The virtualized table improves performance by dynamically rendering only the rows that are visible at any single moment on your page. This means that when a row is scrolled out of view, its node gets removed from the DOM, and if you scroll back up that row needs to be rendered again.

EDIT: I agree with the general feeling that documentation on the feature is poor and could benefit from some examples. Not only basic stuff like shouldCellUpdate: () => false.

Please reopen this issue until it is completely resolved

Released 😃 @zombieJ @afc163 can you please add a working example in the Documentation for this

@zombieJ This issue should not be closed until a permanent solution is provided, can you at please provide a work around since the example you provided is broken?

@zombieJ @afc163 can one of you please add a good example as well for using shouldCellUpdate

The documentation is very poor for this feature. It will be great to see some example of use. Thank you.

@StallionV I totally agree with you

Doesn’t even make sense, i have columns in this way image

try to implement above shouldCellUpdate feature, again it trigger everywhere. Feels like this method is not doing anything, i think it made those check boxes more slower.

Here are the console results of thousands records image

what a pity, feels like wasted time now

Thanks @lorenzocestaro

As I have dynamic data I am adding to every column in the table

shouldCellUpdate: (record, prevRecord) => !_.isEqual(record, prevRecord);

Screenshot 1: image

Click on any page from pagination. Come back to first page. image

As you can see ID is increased. This indicate the Re-render.

Also look at the Console. you can see Re-render

image

Please check again same codesandbox https://codesandbox.io/s/selection-and-operation-ant-design-demo-4co4k?from-embed

check this out https://codesandbox.io/embed/selection-and-operation-ant-design-demo-4co4k?fontsize=14&hidenavigation=1&theme=dark

i couldn’t add virtualizedtableforantd4 as codesandbox was giving error, none the less go through the pagination and you will see that ID is increasing all the times which indicates the re-render @zombieJ

--- "antd": "4.1.5",
+++ "antd": "^4.5.0",

@yoyo837 @zombieJ @afc163 please can you update documentation with examples

Table can not tell what will use in column render function, it always need fully render by default:

const [timestamp, setTimestamp] = React.useState(Date.now());

const columns = [{
  render: () => timestamp,
}];

return <>
    <Table columns={columns}  />
    <button onClick={() => setTimestamp(Date.now())} />
  </>;

But you can use components prop to cache the render: https://codesandbox.io/s/selection-and-operation-ant-design-demo-buogh?file=/index.js

There is some kind of bug in this cache example. Select row number 3 then select row number 2, a then unselect row number 3 and both second and third row are being unselected.

Table can not tell what will use in column render function, it always need fully render by default:

const [timestamp, setTimestamp] = React.useState(Date.now());

const columns = [{
  render: () => timestamp,
}];

return <>
    <Table columns={columns}  />
    <button onClick={() => setTimestamp(Date.now())} />
  </>;

~But you can use components prop to cache the render: https://codesandbox.io/s/selection-and-operation-ant-design-demo-buogh?file=/index.js~

Update: In 4.3.0. Column will support shouldCellUpdate function to control render logic.