Instant Search MultiIndex reconcile perfromance

Instant Search MultiIndex reconciles every change for every

Hi I am using the React Instant Search to build a multiIndex solution which also uses query suggestion indices and Tabs scoped under particular <Index> to render <Hits>

it has a <InstantSearch> at the top level and as children, it has connected <Index> components for the different indexes and query suggestions.

a CustomSearchBox is connected using connectAutoComplete, which will search across all Index and query suggestion indexes.
The problem is it reconciles for every

If I log the props for the connectedAutoComplete, I can see that for every Index the hits get added 1 by 1 to the connected component, even though it only sends 1 network request.

changing something also makes the connectedComponent run for every <Index>
for every change it reconciles for every i have, not just updating the store, e.g. reconciling 8 times after 1 click for every connected component if I had 8 components…

I would expect 1 change/reconcile/update to the store, not to update connectedAutoComplete for every Index there is, i.e 8 times it will recompute.
Any help would be appreciated. Here is a cut down version of what i have

<InstantSearch indexName="dev_SiteTreeIndex" searchClient={searchClient}>
      <Index indexName="dev_ProgrammeInfoIndex_query_suggestions"></Index>
      <Index indexName="dev_SiteTreeIndex_query_suggestions"></Index>
      <Index indexName="dev_NewsAndEventsIndex_query_suggestions"></Index>
      <Index indexName="dev_MemberIndex_query_suggestions"></Index>
      <CustomSearchBox />


      <Index indexName="dev_SiteTreeIndex">
        <h2>index: dev_SiteTreeIndex</h2>
        <Hits />
      </Index>
      <Index indexName="dev_ProgrammeInfoIndex">
        <h2>index: ProgrammeInfoIndex</h2>
        <Hits />
      </Index>
</InstantSearch>

Happy to talk further and explain this if needed

Hello @heathd
It’s true that in some cases connected components in React InstantSearch get re-rendered more than expected. We need to improve that part, but it’s normally okay in production whereas it could be magnitudes slower in dev mode.
Could you tell us if you have an issue on the production? We’re happy to help.

Hi, I am well aware that it’s extremely slow on development mode, when I build for production it is fine on the web, as most things have decent computing power so reconciling 80 times isn’t an issue.

building for production, still slow on mobile and only an issue for MuliIndex solution

On mobile, however, when selecting a facet to filter by, it can take up to 2 seconds for the reconciliation and propagation, etc to stop and it can finally decide what to render.

I am connecting a few things like autoComplete and connectStateHits e.g.

const CustomSearchBox = connectAutoComplete(
  connectStateResults(CachedSearchBox)
);

Inside of each Index can be connected Refinements. Changing a refinement can take up to 2 seconds on mobile while in the production build.

It seems to get exponentially worse for every Index that you add, where everything seems to retrigger at every stage.

Do you have any suggestions for this or techniques to prevent it?

I have built it how Algolia recommends doing a MultiIndexSearch.

I have also constructed the basic example in Algolia for MultiIndex search and it seems to be the same problem, more indexs = a stupid amound of reconciling. Should not be a feature :wink:

Any help or recommendations would be appreciated

1 Like

Hello @heathd

I did some test:

It seems connectAutoComplete has an issue with re-rendering multiple times whereas connectSearchBox doesn’t in multi-index environment.

However, another point of failure could be your nested usage of connectors. Unfortunately nested connectors could cause unexpected behaviors like what you have now, which we are aware of and need to improve.

Could you help me understand what you have in CachedSearchBox? Which data/function do you need? We could find an alternative to get rid of connectAutoComplete and the nested connectors and do another way.

Hi @eunjae.lee ,

It is as you said, the autoComplete rerenders too often, and adding, connectStateResults makes it worse still. I dont need the stateResults, I was just able to stop actual rerenders early on with isSearchStalled and check if props actually changed, but is a band aid for the recomputing that happens everytime and turns out makes the recompute a bit worse, so I don’t actually need stateResults. I will however need the connectAutoComplete as it provides the hits for my autoComplete component which is the material ui labs autocomplete. Its autocomplete is for query suggestions.

Query suggestions are loaded in the same way as <Index>

in the actual custom searchbox component, i use the hits for the suggestions essentially and the other functionality to control the search box i.e refine and currentRefinement.

This same setup is used in another component too, where our design wants a list of top 5 suggestions currently and also top hits

I have forked and updated your code sandbox

Hello @heathd,

I’m sorry for getting back to you late.
I haven’t figured out a workaround that doesn’t trigger multiple reconciliations. The real fix may take longer time.

But I do have an example that may help you clean things up in your project:

In my sandbox, I create a custom connector which actually doesn’t do much but expose data from multiple indices. By creating a custom connector, you get more control over things.

I hope this helps you a bit.