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

[ListView] Prevent rendering during an interaction? #4359

Closed
aleclarson opened this issue Nov 26, 2015 · 12 comments
Closed

[ListView] Prevent rendering during an interaction? #4359

aleclarson opened this issue Nov 26, 2015 · 12 comments
Labels
JavaScript Resolution: Locked This issue was locked by the bot.

Comments

@aleclarson
Copy link
Contributor

I noticed that extreme jitter occurs if a ListView renders rows during a pan interaction. Is there any way to stop the ListView from rendering rows (maybe using InteractionManager)? Thanks!

@facebook-github-bot
Copy link
Contributor

Hey aleclarson, thanks for reporting this issue!

React Native, as you've probably heard, is getting really popular and truth is we're getting a bit overwhelmed by the activity surrounding it. There are just too many issues for us to manage properly.

  • If this is a feature request or a bug that you would like to be fixed by the team, please report it on Product Pains. It has a ranking feature that lets us focus on the most important issues the community is experiencing.
  • If you don't know how to do something or not sure whether some behavior is expected or a bug, please ask on StackOverflow with the tag react-native or for more real time interactions, ask on Discord in the #react-native channel.
  • We welcome clear issues and PRs that are ready for in-depth discussion; thank you for your contributions!

@brentvatne
Copy link
Collaborator

I implemented this but not sure if it's something that will go into core: #2990

@aleclarson
Copy link
Contributor Author

Fantastic. Thanks, @brentvatne.

Any reason(s) for this not making it into core? It seems to be the only solution for avoiding ListView jitter during animation and user interaction. Isn't that something a lot of people need?

@brentvatne
Copy link
Collaborator

@aleclarson - Well perhaps it could make it actually.. I've been working on something else recently to throttle paging in new rows with requestIdleCallback and had some good success with that too. Combined they make interactions in apps with heavy use of ListViews seem smoother / snappier in a subtle yet certainly noticeable way. Wish I could share a video of a comparison but it's for a private project atm :(

@brentvatne
Copy link
Collaborator

Also, @sahrens is doing a lot of work on ListView :)

@aleclarson
Copy link
Contributor Author

Exciting times! Janky ListViews make me physically ill. 😄

@sahrens
Copy link
Contributor

sahrens commented Dec 7, 2015

I think using interaction manager is something we want to do, although it's not usually a problem because people don't often navigate before the ListView finishes rendering. You may want to adjust your initial size and other variables to mitigate.

requestIdleCallback could be cool too.

cc @nicklockwood

@aleclarson
Copy link
Contributor Author

although it's not usually a problem because people don't often navigate before the ListView finishes rendering

What about long lists? Paging in new rows while the user is scrolling can result in jankiness depending on the complexity of the row view; even if pageSize is limited to one. This is especially noticeable when Image elements are used.

Also, this case could benefit from InteractionManager:

I navigate to a ListView and it starts paging in new rows before its superview has completed its entrance animation.

On a side note, it could be useful to have a preventRowRendering prop in the case that:

I tap something to navigate away from the ListView before it's done paging in new rows. The ListView can be returned to, so it cannot be unmounted.

How does requestIdleCallback work?

@ide
Copy link
Contributor

ide commented Dec 7, 2015

Is there a small but powerful prop we could add to ListView's API to configure the incremental rendering behavior? For example, some people might want to use InteractionManager, some people want to use requestIdleCallback, and others might want to use other heuristics such as capping the number of rows per frame (pageSize).

Here's a first take at an API:

<ListView
   shouldRenderRow={(rowData, sectionId, rowId, <what else?>) => boolean}
/>

For convenience we may want to also pass in the number of rows rendered during this pass of the JS event loop -- implementing pageSize is trivial:

shouldRenderRow={(rowData, sectionId, rowId, numberOfMarginalRowsRendered) =>
  numberOfMarginalRowsRendered < pageSize
}

The main things I like about this approach is that ListView doesn't become more of a monster API and it pushes the complexity out of the component and into userspace.

@sahrens
Copy link
Contributor

sahrens commented Dec 8, 2015

Another option would be to inject a task queue into ListView, which could
be InteractionManager, or a simple queue that checks a shouldRenderRow
function? Seems like maybe the most flexible option?

On Monday, December 7, 2015, James Ide notifications@github.com wrote:

Is there a small but powerful prop we could add to ListView's API to
configure the incremental rendering behavior? For example, some people
might want to use InteractionManager, some people want to use
requestIdleCallback, and others might want to use other heuristics such as
capping the number of rows per frame (pageSize).

Here's a first take at an API:

<ListView
shouldRenderRow={(rowData, sectionId, rowId, <what else?>) => boolean}/>

For convenience we may want to also pass in the number of rows rendered
during this pass of the JS event loop -- implementing pageSize is trivial:

shouldRenderRow={(rowData, sectionId, rowId, numberOfMarginalRowsRendered) =>
numberOfMarginalRowsRendered < pageSize
}

The main things I like about this approach is that ListView doesn't become
more of a monster API and it pushes the complexity out of the component and
into userspace.


Reply to this email directly or view it on GitHub
#4359 (comment)
.

@machard
Copy link
Contributor

machard commented Jan 19, 2016

it does not solve all the problems listed here but for navigation fluidity related problems, you can check https://github.com/machard/react-native-advanced-navigation
The approach is to have scenes wrapped in a StaticContainer with shouldUpdate={false} when they don't really have focus (all transition animations need to be over)

@mkonicek
Copy link
Contributor

Hi there! This issue is being closed because it has been inactive for a while.

But don't worry, it will live on with ProductPains! Check out its new home: https://productpains.com/post/react-native/listview-prevent-rendering-during-an-interaction

ProductPains helps the community prioritize the most important issues thanks to its voting feature.
It is easy to use - just login with GitHub. GitHub issues have voting too, nevertheless
Product Pains has been very useful in highlighting the top bugs and feature requests:
https://productpains.com/product/react-native?tab=top

Also, if this issue is a bug, please consider sending a pull request with a fix.
We're a small team and rely on the community for bug fixes of issues that don't affect fb apps.

@facebook facebook locked as resolved and limited conversation to collaborators Jul 20, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 20, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
JavaScript Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

8 participants