algolia / vue-instantsearch

👀 Algolia components for building search UIs with Vue.js
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/vue
MIT License
854 stars 157 forks source link

transform-items called multiple times #707

Closed mategvo closed 1 year ago

mategvo commented 5 years ago

Bug 🐞

What is the current behavior?

transform-items called multiple times on ais-infinite-hits. For each ais-refinement-list component there will be another extra call made. In my case it's 12 calls, which makes the website glitchy.

Make a sandbox with the current behavior

https://codesandbox.io/s/vue-instantsearch-v2-starter-f7o8b?fontsize=14

What is the expected behavior?

call transoform-items only once, after new hits are added.

When the items are transformed vue refreshes item-template. In my case it's masonry layout with quite large images. So transform-items is too expensive to be called multiple times.

Does this happen only in specific situations?

When changing filters (please click on a product title in sandbox to change optional filter brand name). Console will log when transform-items is called.

What is the proposed solution?

Call transform-items only once, when the hits are added.

What is the version you are using?

vue-instantsearch ^2.3.0 (updated today)

Haroenv commented 5 years ago

Hi @mateuszgwozdz, I don't see any superficial calls to transformItems, because when you add a filter, it's likely the result set will be different. If we would do a check to see if the elements are identical, it would likely be much slower than just calling the transformItems function on every change.

However, are you describing it being called multiple times for a single refinement? I can't reproduce that for the demo you sent. Every change in parameters only calls transformItems once

mategvo commented 5 years ago

Have you clicked on a hit f.e. "Motorola - MOTO G (4th Generation) 4G LTE with 16GB Memory Cell Phone (Unlocked) - Black" on the right side of the intreface? The console output should be:

setting optional filters brand:Motorola 
transforming items 
transforming items 
transforming items 
transforming items 
transforming items 
transforming items 

and as you can see above, that'd be six tranform-items calls for a single filter change (I added more refinment components so you can better understand this is problematic)

mategvo commented 5 years ago

@Haroenv even more problematic is that results are requested multiple times as well. Upon inspection of network pane you will see this, for every click:

Screenshot 2019-07-31 at 14 22 55
Haroenv commented 5 years ago

The multiple identical queries can be fixed by adding algoliasearch(xxx, xxx, { _useRequestCache: true }), but I still don't see how in that UI you are rerendering the page (any rerender will cause a request, maybe identical as an existing one if it hasn't finished yet)

patkeav commented 4 years ago

I am noticing this issue too. Using vue-instantsearch 2.7.0. When using several refinements lists, the call to transform-items is happening multiple times.

Screen Shot 2020-03-31 at 9 59 26 AM

It looks to happen as many times as there are refinement lists, as we have 6. It is also calling it 6 additional times each time the results are refined. I've looked on the page and there is nothing re-rendering the component, this seems to be coming from algolia.

Tried _useRequestCache, but the call to algoliasearch() didn't seem to accept it.

Any movement on this?

mategvo commented 4 years ago

All you can do for now is to use algoliasearch(xxx, xxx, { _useRequestCache: true }) to prevent multiple queries to be sent to algolia. I don't think re-rendering was/can be fixed

Haroenv commented 4 years ago

Every refinement list gets its own transformation, it’ll get called many times because we need to know what the return value is to be able to use it correctly. What wrong effects do you see in this being called?

If you’re using client v4, it already has request cache by default

patkeav commented 4 years ago

We do dynamic pricing on our site which we call our own database for. We use transformItems to get the full list of results from the query, then loop through each one and compare with our database. The call to transformItems gets called many times so it calls our database each time, which slows performance.

I've tried setting _useRequestCache, but I'm getting another error when using it like so: algoliasearch('applicationId', 'adminApiKey', { _useRequestCache: true });

Object literal may only specify known properties, and '_useRequestCache' does not exist in type 'AlgoliaSearchOptions'.

Is there perhaps another way to get the list of results outside of transformItems?

Haroenv commented 4 years ago

Can you make this in a sandbox please @patkeav? I'm not sure how you are implementing this now :)

As I said, if you're using algoliasearch@4 (which it seems you do), you don't need to pass useRequestCache, as it's the default

Haroenv commented 1 year ago

This will not change any further, transformItems gets called as many times as needed to render