Replacement for ember-data-filter doesn't seems that good

Hi, I have been migrating my ember app to remove any store.filter. I have been trying to follow the best practice by using peekAll and a filter on top of that. But it doesn’t seems to work as well as expected, any subsequent computed property will always be recomputed even if there was no change.

For exemple : https://ember-twiddle.com/3270717ba0634cee730f2a8d580a4334?openFiles=controllers.application.js%2C In here, everytime I add a new “table” to the store, the “sorting” computed property will get recomputed. is there any best practice for that?

thanks

I think this is expected, when you return from the filter CP you’re returning an entirely new array object every time, so the sort CP always observes a change to the filter CP value. For this to work the way you seem to expect the filter CP would probably have to modify the filtered array in-place and return a reference to the same array every time. I’m sure you could probably do this manually but that’s only worth it in what I would consider to be fairly extreme circumstances.

Any particular reason this behavior seems wrong to you? Like are you filtering a massive number of records or something?

Hi @dknutsen, Thanks for your answer. What i am trying to say is that , the twiddle is doing what is expected from ember. But that there is no good way to do what the store “.filter” feature was doing any more. My performance issue is not that much about the filter, (which is expected to be re-computed every-time there is a new object), but all the subsequent computed property (in this case the sorting). In my app I am doing sorting + rendering of a component for each element in my array. and because of the current behavior, all my components get re-rendered every-time I add an element to the store even if the filter, filter them out. Versus using the store().filter feature, was only recomputing the sort and the re-render only when a new element pass the filter condition and not at every element added to the store…

For now the only way that I found to avoid that thrashing is to have an observer on the peekAll, that do the filter and then only update an array if it detect a new object (or one that got removed) and that pass the filter condition. But this seems like an anti-pattern in ember.

Any recommended solution in ember? Thanks

I think the general approach is less to optimize the CP side of things than to optimize the rendering. It’s possible others might have further suggestions but (assuming you’re rendering these components with the each helper) I’d strongly recommend using the key argument for the each helper. From the docs:

Also be aware that using the key option with an each helper can improve re-render performance when an array is replaced with another containing similar items.

So in a template it would look something like this:

{{#each sortedModels key="id" as |model|}}
  {{mycomponent model=model}}
{{/each}}

That tells Ember how it can optimize the re-rendering of the list of components since it now has something to determine what items match the last render

Make sense. So for now I can’t prevent recomputing of everything but I can prevent re-rendering of everything.

Thanks

@momohuri creating a buffer for the filter wouldn’t be very hard if there’s a lot of expensive computations being done on it’s output. Here is a twiddle: https://ember-twiddle.com/2b21509015ed63ffce12b37bebc5acba?openFiles=controllers.application.js%2Ctemplates.components.display-list.hbs

@runspired your solution looks good. it seems a little bit like an anti pattern because “filteredData” have some side effect (“incrementProperty”). And there is a little bit to much code…

But having something like that implemented inside ember would be great in Ember :slight_smile:

Thanks for your time !

Well you did ask for a side-effect :stuck_out_tongue: That’s what buffers are…