-
Notifications
You must be signed in to change notification settings - Fork 13.5k
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
perf(virtual-list): relaxed restrictions for fast path #11297
Conversation
|
||
changeItem() { | ||
const index = Math.floor(Math.random() * this.items.length); | ||
this.items[index].value = Math.floor(Math.random() * 10000); |
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 does not change the item reference and thus is not expected to generate a diff.
this.items[index] = { value: Math.floor(Math.random() * 10000), someMethod: () => '!!' };
is more appropriate.
changes.forEachOperation((item, _, cindex) => { | ||
if (item.previousIndex != null || (cindex < this._recordSize)) { | ||
if (item.previousIndex != null || (cindex < lastRecord)) { |
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.
The if here will only filter out adds after last record.
I tried something like:
// add new record after current position
if (item.previousIndex === null && cindex > lastRecord) {
console.debug('adding record after current position, no recalculation needed');
return;
}
// remove record after current position
if (item.previousIndex > lastRecord && cindex == null) {
console.debug('removing record after current position, no recalculation needed');
return;
}
needClean = true;
to add more explicit checks for filtered out cases (we can probably consolidate them later on)
This now allows 3 cases to not trigger cleaning (the first two obvious, the third not so much).
- Adding a record after lastRecord
- Removing a record after lastRecord
- Changing a record after lastRecord.
When changing the reference of a record, changes is populated with two entries, one for the removed record and on for the added record. So forEachOperation will be triggered twice, with half the info each time.
logs after triggering a random record changed that happened on position 179:
virtual-scroll.ts:451 virtual-scroll, prevIndex: 179 cindex: null lastRecord: 33
virtual-scroll.ts:460 removing record after current position, no recalculation needed
virtual-scroll.ts:451 virtual-scroll, prevIndex: null cindex: 179 lastRecord: 33
virtual-scroll.ts:454 adding record after current position, no recalculation needed
* @hidden | ||
*/ | ||
lastRecord(): number { | ||
const cells = this._cells; |
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.
LastRecord is modified with scrolling and reset only after needChanges is set to true at least once, so after scrolling all the way to the bottom all add/deletes/updates (except appends) will take slow path until a complete recalculation takes place, even if in the mean time I have scrolled all the way up to the bottom.
Not sure if there is a better approach on this, just pointing out the current state.
I have also noticed that setting virtualTrackBy has no effect, as when the |
@masimplo feel free to clone this PR and submit a new one, unfortunately I have to work in some keyboard issues during this cycle, but I will re-evaluate the virtual-list performance in the next cycle. Another improvement we could make, in slow path we don't need to purge the array of nodes, since we could reuse them. This way we would save the need to recreate all the embedded views each time the slow path is taken. |
// add new record after current position | ||
if (pindex === null && (cindex < lastRecord)) { | ||
console.debug('adding record after current position, no recalculation needed'); | ||
needClean = true; |
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 might just be getting late for me, but shouldn't needClean = true
be outside/after these two ifs since it should happen in all other cases?
10494c9
to
8baa647
Compare
Read your code again with a clear head and I was mistaken about the earlier comments. The comments confused me, because they state the exactly opposite of what you are actually doing.
I guess I should know better. Code never lies, comments... sometimes. 👨💻 Will be now closing #11491 in favour of this one. Thanks for the effort Manu, really appreciate you taking the time and dealing with this on the side. If you ever get virtual scroll into your crosshairs again it would be nice if you could find a way for updates to not cause destroying of the rendered elements at all as you mentioned the other day
|
Short description of what this resolves:
Changes proposed in this pull request:
Ionic Version: 1.x / 2.x / 3.x
Fixes: #