Expensify / react-native-onyx

Persistent, offline-first state management solution for React Native. Easy to use with minimal config and boilerplate.
MIT License
151 stars 71 forks source link

Remove null values from cache to improve Onyx read speed #554

Closed chrispader closed 3 months ago

chrispader commented 3 months ago

@mountiny @neil-marcellini

Details

Removes null values from OnyxCache (reads) and therefore removes unnecessary calls to removeNestedNullValues on read.

This PR adds a nullishStorageKeys Set to OnyxCache where a key can be added in order for the key to represent null/"not set" in cache. This change let's us keep existing performance and loading state improvements that @janicduplessis implemented in https://github.com/Expensify/react-native-onyx/pull/401.

This PR also adds some general code quality improvements around using the cache and handling reads and writes to Onyx.

Recently IDBKeyvalProvider hasn't been identical in it's behavior to SQLiteStorageProvider. Therefore, i added some extra logic to setItem, multiSet and multiMerge, to check for null values and handle those in the storage layer.

Related Issues

https://github.com/Expensify/react-native-onyx/issues/553 https://github.com/Expensify/App/issues/42654

Automated Tests

Manual Tests

Author Checklist

Screenshots/Videos

Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
MacOS: Desktop
neil-marcellini commented 3 months ago

Requesting a review from myself so this doesn't get lost, but planning to let Janic review first.

chrispader commented 3 months ago

This PR seems to be the fix for a regression in https://github.com/Expensify/App/pull/42057, which was reverted in https://github.com/Expensify/App/pull/42725

@neil-marcellini @janicduplessis i'm gonna prioritize this PR right now so we can hopefully merge this today. I'll let you guys know when i'm done with the implementation so you can review

cc @mountiny

chrispader commented 3 months ago

@neil-marcellini @mountiny @janicduplessis this PR is now ready for review! Once we merged this, we can review, QA and merge https://github.com/Expensify/App/pull/42772

chrispader commented 3 months ago

@mountiny addressed all your comments and improved a few other parts of the implementation

github-actions[bot] commented 3 months ago

🚀Published to npm in v2.0.43

ahmedGaber93 commented 3 months ago

Coming from this issue https://github.com/Expensify/App/issues/42529. useOnyx in useReportIDs.tsx here are sent reportActions with null values to the E/App. I see this PR remove null values from cache and I test the issue with this fix in v2.0.43 and it fixed.

@chrispader I just need to confirm if this PR fix the above issue because its title indicates it is for improve performance

chrispader commented 3 months ago

Coming from this issue Expensify/App#42529. useOnyx in useReportIDs.tsx here are sent reportActions with null values to the E/App. I see this PR remove null values from cache and I test the issue with this fix in v2.0.43 and it fixed.

@chrispader I just need to confirm if this PR fix the above issue because its title indicates it is for improve performance

@ahmedGaber93 this PR is also supposed to remove null values from all getter options, like withOnyx, useOnyx and Onyx.connect. If this PR fixed your issue, it should be fine!

ahmedGaber93 commented 3 months ago

Coming from this issue https://github.com/Expensify/App/issues/42529. E/App still receive null values in Onyx.connet here. For reproduce steps see issue description. I think we can add an extra null check in E/App to urgent fix, but this is still needing to fix.

chrispader commented 3 months ago

Coming from this issue Expensify/App#42529. E/App still receive null values in Onyx.connet here. For reproduce steps see issue description. I think we can add an extra null check in E/App to urgent fix, but this is still needing to fix.

I couldn't reproduce this myself, but i suppose this stems from old data (with null values) still being in storage, which is then returned.

We only remove null values on write, so unless a key doesn't change in the meantime, it will still hold the null value

@ahmedGaber93 could you link me to the exact repro steps? the ones from the issue description don't give me this problem

chrispader commented 3 months ago

@ahmedGaber93 You mean exact null values right? because Onyx can still return an object that includes keys that are undefined. This would also lead to report actions being filtered out by Boolean(value)