-
Notifications
You must be signed in to change notification settings - Fork 555
Description
🐛 Current behavior
A circular/recursive reference is created by the createURL and searchForItems functions in the refinementList connector which are passed to the refinementList render function. This causes all past search states and hits to be retained in memory and increases the depth on every search.
🔍 Steps to reproduce
- Go to the InstantSearch.js template sandbox
- Open in new tab
- Open devtools and go to the memory tab
- Do anything that executes a search several times.
- Click the "Collect Garbage" button in devtools
- Select profiling type "Heap Snapshot"
- Click the "Take Snapshot" button
- Sort by Retained Size descending
- Expand the list of {instantsearch} objects. It should be near the top when sorted by retained size if enough searches were executed.
- Select an {instantsearch} object to see it in the Retainers section. Pick one with a high distance.
- In the expanded objects in the retainers section note multiple instances of createURL and searchForItems
- Hover over refinementList to see its retaining objects. If you do this for refinementList at multiple distances you will note that the retaining object "hits" has different values at different distances indicating that all search results have been retained in memory since the search app was started.
Google Drive Video since the file was rather large.
Live reproduction
https://codesandbox.io/s/github/algolia/instantsearch/tree/templates/instantsearch.js
💭 Expected behavior
In the case that these circular/recursive references to past searches and states is necessary, expected behavior would be to limit them so that only a certain number is retained. Otherwise, I believe expected behavior would be to somehow limit the context that createURL and searchForItems have access to so that they don't retain large objects like previous search states and results.
In my own app, instead of writing a new connector, I used a workaround. In the last widget to be rendered I added instantSearchInstance.renderState.MyIndex.refinementList = null; to the end of the custom render function. I expect this is a bad solution and might break things, but it seems to have done the trick in my case.
Package version
instantsearch.js 4.79.1
Operating system
Windows 11
Browser
Chrome Version 138.0.7204.101 (Official Build) (64-bit)
Code of Conduct
- I agree to follow this project's Code of Conduct