Calling `conversations.list()` is SLOW
Thanks for this lib and this sample app!
However, I'm having really bad performance with it, do you know if that's normal?
A classic conversations.list() usually takes 2-3 seconds when in the browser or NodeJS.
But in the react native environment it takes 42 seconds in the simulator and 58 seconds on my iPhone!
Using the wallet created in app (that's empty) it is almost immediate Using my own wallet that has 7 conversations on the testnet it takes a very long time
Here is an example code diff to show you what I did in the app (pretty straightforward) : https://github.com/xmtp/example-chat-react-native/compare/main...nmalzieu:xmtp-react-native:main
Do tell me if you want more information or if we should hop on a call to debug together

Doing further tests, I tried to split the two list methods here: https://github.com/xmtp/xmtp-js/blob/main/src/conversations/Conversations.ts#L88-L89
and it seems that listV1Conversations takes like 25 seconds (I have just 4 of them) and listV2Conversations takes 5 seconds (I have 31 of them)
So probably an issue with v1 conversations, if that can help?
@nmalzieu Thank you for filing this and I can reproduce the slowness very easily just calling conversations.list(). In one of my authenticated wallets it's taking 257 SECONDS 😱 . There are a few things that could be going on here:
- One or many of our polyfills acting slowly
- Maxing out CPU
- Something slow within Hermes as our JS engine
I'll take a quick look today to try and track down the slowness, but one alternative that might be worth investigating in the meantime is using the xmtp-js library directly in a webview to avoid the polyfills. Hopefully that is much more performant!
I did some testing between using JavaScriptCore and Hermes on iOS and Hermes seems to be a big bottleneck here. If I disable Hermes in our Podfile, then I can get a cold load of 250 convos in ~3s with a follow-up call taking less than 1s due to caching in our SDK.
If I turn Hermes back on, I notice the cold conversations load significantly slows down to ~1m and even the cached version takes seconds.
| With Hermes | With JavaScriptCore |
|---|---|
![]() |
![]() |
Next steps: Try to get V8 JavaScript engine working for Android so we can move off Hermes and commit these changes. V8 and iOS 14 will be necessary since we require BigInts in our SDK and BigInt doesn't exist on JSC iOS prior to iOS 14 or on JSC Android at all.
Hi @elisealix22 , thanks I'll try to reproduce! Do you think the solution is to switch to JSC? Or do you think we could pinpoint what exactly is slow in Hermes (a network call? a serialization?) to maybe make it work with Hermes as it is supposed to be faster and more efficient?
@nmalzieu Here's the diff of the branch where I had that working with the Generate wallet flow in case it helps!
Do you think the solution is to switch to JSC? Or do you think we could pinpoint what exactly is slow in Hermes (a network call? a serialization?) to maybe make it work with Hermes as it is supposed to be faster and more efficient?
Honestly too soon to call. I don't think either are going to be an easy lift. My instinct was that maybe it's time to switch to JSC/V8 because it's not the first time we've run into performance issues on Hermes. Also, it's noticeably faster to create the 250 convos in the loop on JSC for iOS as well. That said, I have yet to get Android up and running so I think both options are up in the air and need more investigation.
Update: Using Hermes is a requirement for some so we're going to have to dig in more to figure out what calls are the bottleneck in that environment.
Thanks @elisealix22
I actually can't see any difference in Converse by using Hermes or not.
It is a bit better now, but still I see great performance improvement if I disable the this.listV1Conversations in Conversation.ts - seems v2 convos are a lot faster to list…
Other issue: it seems to be a bit CPU-intensive and blocking the UI. Like, when doing conversation.list I can't navigate in the app until it's finished (and since it takes a bit of time it's not great)
It is a classic React Native issue but not sure how to fix it (run some stuff in sub threads?)

