1

I have been porting my old app from Redux to Zustand, and it's so much cleaner and nicer now.

However, I am hitting a few problems, and I am wondering what the best way forward is. I am making a podcast application, and the users visit a lot of podcasts. In the old app I would use localForage (also IndexedDB) to have a cache of podcasts, where each podcast had a key. When I wanted to read the podcast data I would read that cache, and after any changes save the cache again.

With Zustand I've tried to keep all those podcasts in a state.podcastCache object with their unique identifier as key. This seems to work very nicely. However I've recently started to get Out of Memory errors. This typically happens when I update the state often (even if no new content comes in) - eg. a simple change like updating state.podcastCache[uniquid].episodes[0].playedTime = currentTime;

So I am wondering a few options:

  1. Is Zustand keeping all of the state in memory, and this is what's leading to the problem? (I can see in my developer console that the state in IndexedDB is 25MB).
  2. Is 25MB too much for the state? I read online that IndexedDB can easily be several GB's, but I am unsure how large the state can realistically be before things start to go wrong.
  3. Is this the completely wrong way to handle data like this, and should I go back to have a more normal cache layer outside of Zustand?

Basically, any advice or suggestions to solve this problem is very very welcome.

MartinMouritzen
  • 221
  • 1
  • 2
  • 12
  • Thanks for the well written question. It's hard to tell you concretely what's wrong. Do you have a code repo to show? What's the nature of the data you store, just JSON or Blobs as well? To your questions, 25MB is not much, clients can handle much more. Zustand, as well as other state mgmt tools, stores state in memory by default, although you can persist it with middleware. Whether your data handling is incorrect can be said only with the info mentioned above. – Dan Macak Apr 26 '23 at 13:15
  • @Skocdopole That's good to hear. Let me see if I can recreate the problem in a smaller code repo. Based on your answer, I am wondering if my problem lies somewhere else than the size of the state. (also I do persist the state of Zustand with middleware.). Thanks for your quick answer! – MartinMouritzen Apr 26 '23 at 14:05
  • @Skocdopole Okay, so I looked at it a bit more. I have a suspicion that the problem comes from how often I set the state. If I run the memory log in Chrome's Dev Tools, I can see that the number 1 function is the custom store function in Zustand. I save parts of the state every half second (because I update played time on an episode). I am wondering if the set function simply can't keep up, or if it doesn't have time for garbage collecting. – MartinMouritzen Apr 27 '23 at 07:17
  • @Skocdopole Still debugging, and there's a lot of moving parts, but to use IndexedDB I use the following code `const storage = { getItem: async (name) => { return (await get(name)) || null }, setItem: async (name, value) => { await set(name, value) }, removeItem: async (name) => { await del(name) }, }` If I remove "await" from setItem, it does seem to make things better. The app still crashes, but where before it would typically crash within 10 seconds (if the state is large), now it takes at least several minutes. – MartinMouritzen Apr 27 '23 at 07:43
  • Interestingly enough, after that change I don't get the out of memory exception but instead "SBOX_FATAL_MEMORY_EXCEEDED". I am unsure of the difference in those (could potentially also be because my chrome version updated, and they simply changed their error code). I am still hypothesizing that the memory problems come from the whole state being set every half second, which leads to problems, and that I probably need to move to a structure where I keep the cache completely away from the main state. – MartinMouritzen Apr 27 '23 at 07:45
  • There are some hints in what you wrote but I'd still need to see the code. In and of itself, updating state every half a second is not a problem. My feeling is that it triggers a spiral of state updates that drains the memory, but again, hard to say without concrete code. – Dan Macak Apr 27 '23 at 10:51

0 Answers0