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

[Feature] Observe range of array #974

Closed
3 of 4 tasks
zwhitchcox opened this issue Apr 28, 2017 · 4 comments
Closed
3 of 4 tasks

[Feature] Observe range of array #974

zwhitchcox opened this issue Apr 28, 2017 · 4 comments

Comments

@zwhitchcox
Copy link
Contributor

zwhitchcox commented Apr 28, 2017

  1. Idea:
  • What problem would it solve for you?
  • Do you think others will benefit from this change as well and it should in core package (see also mobx-utils)?
  • Are you willing to (attempt) a PR yourself? possibly

So, let's say you have an array, and it's for example a paginated list of some sort. So, you have a bunch of different pages, and let's say those pages are sorted by some value.

Now, let's also say that you're trying to get every bit off efficiency as you can.

Now, the first page only cares about 1 - 99, and the second page only cares about 100 - 199, and so forth.

The problem is, every time the array changes, every single page is going to react to that. So, if someone inserts something that is on page two, page one will re-render.

It would be cool if you could subscribe to a range of an array. So, this reaction only cares about 1 - 99, so if 1 - 99 hasn't changed, don't react, and so forth.

Is this possible? Is there already something like this available or a hack or something? Or am I missing something completely?

Thanks in advance.

@krnaveen14
Copy link

let's say those pages are sorted by some value

If I understand correctly what you're suggesting, Modifying the array should react on whole array instead of a range, else you'll end up with wrong sorting / search / some other criteria.

@urugator
Copy link
Collaborator

urugator commented Apr 29, 2017

The problem is, every time the array changes, every single page is going to react to that. So, if someone inserts something that is on page two, page one will re-render.

Just to clarify, what you actually mean is this:
Every time the array changes, any page which is currently rendered, will get re-rendered, even though the actual content might stay the same.

I think this situation can occur only if the change happens on index, which is higher than last index of current page, otherwise the items on current page will get modified (at least one item is added or removed).
So the range is actually always from 0 to last index of current page.

Putting aside whether this kind of optimization makes sense or not, I think it can be done with existing tools:

If you care only about preventing the render phase, you could represent page items as a computed with compareStructural option turned on (considering the items are structurally comparable, for a custom comparator see #951):

const items = mobx.observable([]);
const pageItems = mobx.computed(() => items.slice(0, 100), { compareStructural: true });

The observers are not notified if the result is structurally equal, so it will prevent re-rendering, however the computation and equality check would still have to re-run any time the items is modified.

The ideal solution for that would be derived arrays, you're welcome to implement them :)

As a "work around" you could use observe to detect which index of items has been affected and replace the items of pageItems when neccessary.

@mweststrate
Copy link
Member

@zwhitchcox can you create a fiddle explaining the problem?

The problem is, every time the array changes, every single page is going to react to that. So, if someone inserts something that is on page two, page one will re-render.

That is in principle not the case, as long as you ensure both the component mapping over the array, and the components that actually render the page are both observer. Sure all page components are reconciled, but they should not re-render.

Or where you concerned about the reconciliation? If you want to break a computation into smaller sub parts, to max out performance, also see createTransformer, it is quite an abstract, but powerful mechanism to get max out performance by introducing more intermediate caching points.

@zwhitchcox
Copy link
Contributor Author

Awesome! I didn't know that....I'll give it a try and report back if I have any problems

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants