Skip to content

[HOLD for payment 2024-07-17] LOW: [HOLD] Create secondary maps for connection keys in Onyx #35809

Description

@mountiny

Coming from here

Problem

On the connect from Onyx, we store in a map (callbackToStateMapping) a unique connectionID with a mapping of the connected component (which has all the information about the component and configs), in that mapping there is a key which is the used in the withOnyx or the raw Onyx.connext to listen for value changes.

When a value for a key changes, the function keyChanged or keysChanged (if it is a collection) is being called, passing the key and some data. What that function does is, get all the connection IDs from the callbackToStateMapping, and goes through all the items checking if that connection has the key that changed. This could be a really low process, because it look into all the keys connected in the app, and as we can see in the screenshot, a really small account with a few chats and messages can create hundred of connections, and on top of that, the keyChanged function can be called multiple times.

Solution

Create a secondary map, which is the Key that is being listen (like session) and an array of connection IDs that uses that key. This will improve the look up and sending the changes because it look for the connections that are being listening to that Key.

// on connect function
+    if (!onyxKeyToConnectionIDs.has(mapping.key)) {
+        onyxKeyToConnectionIDs.set(mapping.key, []);
+    }
+    onyxKeyToConnectionIDs.get(mapping.key).push(connectionID);

// on keyChanged/keysChanged function
-    const stateMappingKeys = _.keys(callbackToStateMapping);
+    const stateMappingKeys = onyxKeyToConnectionIDs.get(key);

// on disconnect function
+    if (onyxKeyToConnectionIDs.has(keyToDelete)) {
+        onyxKeyToConnectionIDs.set(keyToDelete, _.without(onyxKeyToConnectionIDs.get(keyToDelete), connectionID));
+    }

Running a performance test on the keyChanged function we can notice a big improvement: onyx notify connections [function]: 13.7 ms → 1.5 ms (-12.2 ms, -88.9%) 🟢🟢 | 1 → 1
(this test created around 10k of keys and connections)
We did some tests on Android Production build and we got some results:
Report Load:
Hot load:
without patch -> 3677 ms
with patch -> 3380 ms
Improvement -> 300ms
Cold load:
without patch -> 34936 ms
with patch -> 4756 ms
Improvement -> 30180 ms ‼️

Issue OwnerCurrent Issue Owner: @johncschuster / @anmurali
Issue OwnerCurrent Issue Owner: @johncschuster / @anmurali

Metadata

Metadata

Labels

Awaiting PaymentAuto-added when associated PR is deployed to productionDailyKSv2NewFeatureSomething to build that is a new item.

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions