-
Notifications
You must be signed in to change notification settings - Fork 24.3k
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
Optimize VirtualizedList #31327
Optimize VirtualizedList #31327
Conversation
Base commit: a15a46c |
84da4e5
to
cdf3dd6
Compare
cdf3dd6
to
5f960ef
Compare
@halaei I've applied the patch and performance seems improved, I've faced an issue with |
Isn't that optimized by using |
... | ||
}; | ||
|
||
class CellRenderer extends React.Component< | ||
class CellRenderer extends React.PureComponent< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This component accepts props which changes every render, so I think PureComponent
checks will be false every time:
onLayout
- can be fixedparentProps
- can't be fixed- Maybe more?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onLayout
doesn't seem to cause extra renders in my manual tests. It's input value is given by the creator passed to _pushCell()
function, which is only called when needed. So caching already is applied to onLayout
too.
I think maybe for some use-cases there can be more optimization, for example not always everyone needs all the fields in parentProps, and sometimes the order and number of items in data
doesn't change the internal of an item component, so maybe ii
can be removed from deps
too. I am interested to see other improvements done too.
Simply wrapping the return value of renderItem() inside a React.memo or returning a React.PureComponent doesn't help: const ItemComponent = (props) => {
x =...
y = ...
z = ...
return <ComponentDependingOn_x_y_z ...>;
}
const MemoItemComponent = React.memo(ItemComponent); // It doesn't prevent extra re-renders because props always change by each call to VirtualizedList.render(). However using memoiztion techniques inside the component prevents extra renders of the nested component const UseMemoItemCompont = (props) =>{
x =...
y = ...
z = ...
return React.useMemo(() => {
return <ComponentDependingOn_x_y_z ...>;
}, [x, y, z]);
} So I think this PR has the following values: |
It's not safe to memoize a React Element. It could be using some state in the component which However, if it was something like |
I tested with a simple SectionList and it worked for me. Also current tests are passed. Can you give an example SectionList that fails? |
Any info about the status of this request ? |
I am also interested to have feedback. I've just checked this PR with master branch and PR #31401 for more tests. All tests passed. |
Could You check this optimization on RTL mode? In RTL We don't have 'sleep' phase, and as You write should be work the same as in LTR mode, render initialNumRender first and sleep, render second , sleep. etc. |
This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
This PR was closed because it has been stalled for 7 days with no activity. |
Summary
Using FlatList components with 50 items, and the default values for
initialNumToRender
andmaxToRenderPerBatch
, the following happens:So the flat list is rendering the first 10 items 5 times. It is a performance issue when the items are complicated, or the FlatList has many items. Having N items the FlatList will render O(N^2) items over time.
This PR reduces time complexity by:
VirtualizedList
and reusing the components in consecetive calls tolist.render()
.CellRenderer
aReact.PureComponent
and re-shaping state to prevent re-renders.Possibly related issues
renderItem
renders twice, instead of once #18396...
Changelog
[JavaScript] [Fixed] - Don't render list items if not changed.
Test Plan
Some tests are needed to make sure that all the cached components are rendered just enough, no more/less.
Footer, header, and cell components are cached. Other child components don't need to be cached because they are either simple or rendered once.