instantsearch icon indicating copy to clipboard operation
instantsearch copied to clipboard

Sort refinementList values before sending HTTP request (so request caching works as expected)

Open websocket98765 opened this issue 4 years ago • 3 comments

Deleting my OP to not cause confusion. See my two posts below for the remaining issue, which is refinement list values should probably be sorted before building HTTP request string.

Environment:

  • OS: Mac
  • Browser: Chrome (Reproduced in Firefox & Safari too)
  • Version: "react-instantsearch-dom": "^6.5.0",

websocket98765 avatar May 29 '20 00:05 websocket98765

Fixed by two things:

  1. updating algoliasearch from 3.x to 4.2.0.
  2. For my custom refinement, I now sort the values before calling refine(values), otherwise the first request (triggered via onExternalStateUpdate()) would sometimes have facet values for this refinement listed in order foo bar, but when onWidgetsUpdate() was invoked, these values are reordered alphabetically to bar foo (to paraphrase, this isn't direct from the request URL), causing the cache to miss.

I'm leaving this issue open for team to consider if the lib should sort refinement values before creating the request URL, to ensure the HTTP cache will hit properly.

websocket98765 avatar Jun 02 '20 01:06 websocket98765

Hi @websocket98765 Thanks for the detail in this issue. I'm sorry but I couldn't reproduce it. I may not understand the issue correctly.

https://codesandbox.io/s/optimistic-carson-ep7z1?file=/src/App.js:1736-1850

I tried a little bit there. If you don't mind, could you update it to reproduce the issue?

eunjae-lee avatar Jun 02 '20 12:06 eunjae-lee

This one is honestly a lot of work to build a demo to repro. Just ignore my OP in this thread, since I identified the cause in the 2nd comment, which is:

You may want to consider sorting values in a refinement list before building the HTTP request to be sent. Otherwise, if a user has a custom refinement and calls refine(value) with a non-alphabetical order, e.g. where value is ['wide','narrow'], algolia will send 2 http requests--the first containing the non-alphabetized refinement list items (initiated via onExternalStateUpdate()) and the 2nd containing the list now alphabetized (initiated via onWidgetsUpdate()).

The first request contains:

facetFilters: ["foo:wide","foo:narrow"]

and the 2nd contains the same but is alphabetized:

facetFilters: ["foo:narrow","foo:wide"]

The takeaway is that, because the ordering is different in the request URL, the request cache will miss, even though the URL is the same otherwise, thus causing 2x requests to Algolia when any UI element is changed and this condition exists.

The solution in my code: use refine(values.sort()) in my custom refinement. Suggested solution: consider sorting refinement list values alphabetically in the lib before building the request URL

I have this fixed in my code, so no worries on that, just depends if you think this affects others or not.

websocket98765 avatar Jun 02 '20 16:06 websocket98765