-
Notifications
You must be signed in to change notification settings - Fork 577
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
Efficient React ListView for Realm collections #199
Conversation
retest this please |
const TodoListItem = require('./todo-list-item'); | ||
const realm = require('./realm'); | ||
const styles = require('./styles'); | ||
|
||
const { ListView, Text, View } = React; | ||
const { Text, View } = React; | ||
const { ListView } = RealmReact; |
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.
Should we consider naming it RealmListView
to differentiate? This is fine if it is the convention but may be confusing.
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.
No because it's supposed to be a drop-in replacement and it's namespace under the RealmReact
module. So it's really called RealmReact.ListView
.
Have we done any testing to see how this effects performance? Would be good to know if this resolves any of the issues reported. We should also probably write tests for this. |
I have a separate test app where I fine tuned this to work with a reasonably large dataset (100,000 items). It removed all the JS bottlenecks, but there's definitely a performance issue with using large sorted results (inside core) that I will dive more into when I address #193. I don't think the overhead of creating UI tests for this will be worth the effort at this point. |
}); | ||
|
||
this.state = {}; | ||
this.state = { | ||
dataSource: this._cloneDataSource(dataSource, props), |
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.
I haven't been following the evolution completely so maybe I am missing something, but it seems odd to me that a data source would be state rather than a property or just a variable.
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.
It is a bit weird at first, but since a dataSource
is completely immutable it makes sense because the canonical way to update it is to clone it and call setState
. Otherwise you'd need to call forceUpdate
, which is kind of an anti-pattern in React.
Playing around with this a bit it looks like we have some perf issues. I added this code to the TodoApp constructor to populate the initial list with 1000 items: let list = realm.create('TodoList', {name: 'Todo List', items: []});
for (var i = 0; i < 1000; i++) {
list.items.push({text: '' + i});
}; After doing this scrolling performance is pretty bad, and there is a noticeable lag when mutating the list by removing items. The lag increases to further you scroll down - once you get down to around 300 items the ui takes about a second to update. It would be nice to know where this lag is coming from and to eliminate it if possible. |
I had to dive in pretty deep with the JavaScriptCore profiler to understand what's going here. This delay is overwhelmingly caused by React validating props, which is only enabled on debug builds. When built in Release mode, this problem should go away. However, we don't have the necessary build phase in the example app to bundle the release version of the JS (I will update this branch with that phase). You can get the release version of the JS by appending |
I opened PR #202 with updates to the way the example app chooses its JS. |
I think this is fine other than the fact that we don't have tests verifying that this works. It is likely that at some point react-native will change and this will break. I think at a minimum we should add ui tests to the example app to make sure list items actually show up using our ListView. Since this is something we have been meaning to do anyway it may make sense to make it happen with this pr. |
Ok, I'll try to tackle a basic version of that for this PR. |
This would unfortunately result in adverse performance side effects because calling size() can be expensive.
This component is fully backwards compatible with the original React ListView, but is compatible with Realm Results and List objects to use their snapshot functionality along with more efficiently checking if each row should update.
It's also been updated to follow best practices with how to properly use the ListView data source.
This caused an error with NPM v3 and was not necessary for us to have.
* master: (207 commits) Convert to using new React Native MainActivity template Create RealmReactPackage for our Android plugin Fix doc for Android NPM ignore react-native/android folder Skip building Android module under Xcode Skip building Android module for iOS tests gitignore Android downloads folder Update README with instructions to run on Android Use un-patched RN for Android by installing hook into JSC cleanup build system Use Realm in node_modules for ReactTests on Android Change Demo => ReactTests adding a 'publishAndroid' task to generate the AAR with prebuilt .so files Adjust POM_NAME Use consistent package naming Remove old Demo files Add copyright to JNI file Cleanup platform.hpp Make our Android module buildable as a dependency Add `npm test` command ...
These changes include timeouts when waiting on notifications.
Re-using the existing React testing class to hook into the example app. Right now, the test is extremely basic but is able to be expanded later. Resolves #36
@alazier this is ready for review. It includes the |
Efficient React ListView for Realm collections
This component is fully backwards compatible with the original React
ListView
, but is compatible with RealmResults
andList
objects to use their snapshot functionality along with more efficiently checking if each row should update.This resolves #142 and #36