Skip to content

Commit

Permalink
Merge pull request #576 from callstack-internal/perf/use-startswith-only
Browse files Browse the repository at this point in the history
perf: avoid re-calculating collection key length and use key.startsWith
  • Loading branch information
MariaHCD authored Aug 7, 2024
2 parents 190d8d1 + eee10ec commit 9605e91
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 6 deletions.
3 changes: 2 additions & 1 deletion lib/Onyx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,7 @@ function updateSnapshots(data: OnyxUpdate[]) {
const promises: Array<() => Promise<void>> = [];

const snapshotCollection = OnyxUtils.getCachedCollection(snapshotCollectionKey);
const snapshotCollectionKeyLength = snapshotCollectionKey.length;

Object.entries(snapshotCollection).forEach(([snapshotKey, snapshotValue]) => {
// Snapshots may not be present in cache. We don't know how to update them so we skip.
Expand All @@ -656,7 +657,7 @@ function updateSnapshots(data: OnyxUpdate[]) {

data.forEach(({key, value}) => {
// snapshots are normal keys so we want to skip update if they are written to Onyx
if (OnyxUtils.isCollectionMemberKey(snapshotCollectionKey, key)) {
if (OnyxUtils.isCollectionMemberKey(snapshotCollectionKey, key, snapshotCollectionKeyLength)) {
return;
}

Expand Down
11 changes: 7 additions & 4 deletions lib/OnyxUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,8 @@ function isCollectionKey(key: OnyxKey): key is CollectionKeyBase {
return onyxCollectionKeySet.has(key);
}

function isCollectionMemberKey<TCollectionKey extends CollectionKeyBase>(collectionKey: TCollectionKey, key: string): key is `${TCollectionKey}${string}` {
return Str.startsWith(key, collectionKey) && key.length > collectionKey.length;
function isCollectionMemberKey<TCollectionKey extends CollectionKeyBase>(collectionKey: TCollectionKey, key: string, collectionKeyLength: number): key is `${TCollectionKey}${string}` {
return key.startsWith(collectionKey) && key.length > collectionKeyLength;
}

/**
Expand Down Expand Up @@ -556,12 +556,14 @@ function getCachedCollection<TKey extends CollectionKeyBase>(collectionKey: TKey
const allKeys = collectionMemberKeys || cache.getAllKeys();
const collection: OnyxCollection<KeyValueMapping[TKey]> = {};

const collectionKeyLength = collectionKey.length;

// forEach exists on both Set and Array
allKeys.forEach((key) => {
// If we don't have collectionMemberKeys array then we have to check whether a key is a collection member key.
// Because in that case the keys will be coming from `cache.getAllKeys()` and we need to filter out the keys that
// are not part of the collection.
if (!collectionMemberKeys && !isCollectionMemberKey(collectionKey, key)) {
if (!collectionMemberKeys && !isCollectionMemberKey(collectionKey, key, collectionKeyLength)) {
return;
}

Expand Down Expand Up @@ -597,6 +599,7 @@ function keysChanged<TKey extends CollectionKeyBase>(
// individual collection key member for the collection that is being updated. It is important to note that the collection parameter cane be a PARTIAL collection
// and does not represent all of the combined keys and values for a collection key. It is just the "new" data that was merged in via mergeCollection().
const stateMappingKeys = Object.keys(callbackToStateMapping);
const collectionKeyLength = collectionKey.length;
for (let i = 0; i < stateMappingKeys.length; i++) {
const subscriber = callbackToStateMapping[stateMappingKeys[i]];
if (!subscriber) {
Expand All @@ -616,7 +619,7 @@ function keysChanged<TKey extends CollectionKeyBase>(
/**
* e.g. Onyx.connect({key: `${ONYXKEYS.COLLECTION.REPORT}{reportID}`, callback: ...});
*/
const isSubscribedToCollectionMemberKey = isCollectionMemberKey(collectionKey, subscriber.key);
const isSubscribedToCollectionMemberKey = isCollectionMemberKey(collectionKey, subscriber.key, collectionKeyLength);

// Regular Onyx.connect() subscriber found.
if (typeof subscriber.callback === 'function') {
Expand Down
6 changes: 5 additions & 1 deletion lib/useOnyx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(key: TKey
const previousCollectionKey = OnyxUtils.splitCollectionMemberKey(previousKey)[0];
const collectionKey = OnyxUtils.splitCollectionMemberKey(key)[0];

if (OnyxUtils.isCollectionMemberKey(previousCollectionKey, previousKey) && OnyxUtils.isCollectionMemberKey(collectionKey, key) && previousCollectionKey === collectionKey) {
if (
OnyxUtils.isCollectionMemberKey(previousCollectionKey, previousKey, previousCollectionKey.length) &&
OnyxUtils.isCollectionMemberKey(collectionKey, key, collectionKey.length) &&
previousCollectionKey === collectionKey
) {
return;
}
} catch (e) {
Expand Down

0 comments on commit 9605e91

Please sign in to comment.