-
Notifications
You must be signed in to change notification settings - Fork 731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Looking for recommendation for Pagination + Watching flow #1393
Comments
Hey @bharath2020 - just a heads up that I'm bogged down at the moment but this is a very good question that I need to work on a better answer to (and that we should have a way better answer to overall for mobile), and I think messing around with the tutorial is probably a good place to start with it. And you are very correct that 10 seconds to read 150 items is 🤮. In terms of what you can try while I'm digging out from under what I'm dealing with now, there's the I'm going to leave this open for the community to respond more - I know this has been done well, but my knowledge of details isn't there because I'm focused on other parts of the SDK at the moment. |
Thanks, @designatednerd for the response.
Interesting. In approach #2, Given that I am appending items from P.S. I have cacheKeyForObject enabled in my sample, and timings were taken after. The only part where I would not be able to generate a cache key is for the |
Again, my knowledge of the cache is not as deep as it should be, but my understanding is you'd be rewriting the references with IDs rather than the entire object and its entire tree of changes. This almost certainly has some unnecessary work, but it would likely constitute a lot less unnecessary work than without the And again, this is not working as well as we want it to. We have some changes to the cache slated for phases 2 and 3 of the ongoing Swift codegen rewrite, and making things less annoying for pagination is one of the major things I want to do within that work. Wish I had a better answer for you. |
Got it. I played a little bit with batch reading objects from the database. I will give it a try to see if we can do the batch updates within a transaction. Right now, each roundtrip to the SQLite database is in its own transaction and I am guessing that is causing the reads to slow down. I have in the past read a huge number of items from SQLite and latency was fine. I will see if it makes any difference in the same and post it back. |
OK - do you mind if we close out this issue? |
Ok |
We have solved this problem using a third approach page normally using queries. Then use a watcher to watch only the currently visible page. |
(Have this question posted in Spectrum chat as well, Adding here for better reach. Apologize for noise.)
Problem
We have done some experiments in adopting pagination and encountered a few issues. I am looking for a recommendation on how to extract paginated results that do achieve two of my main goals. For the context, we have a mobile application that has screens that show paginated content that allows infinite vertical scrolling.
For example, assume the following schema
Here are the approaches we tried:
Approach 1: Follow the suggestion as per the Apollo iOS tutorial blog
Issues with Approach 1
1. Zombie records:
Following the query path approach to generate cache key, the First page will be written under cache key "QUERY_ROOT.getPage-cursor", while subsequent pages will hold the items under the cache key "QUERY_ROOT.getItems-cursor-page2cursor", "QUERY_ROOT.getItems-cursor-page3cursor", and so on..
In our case, The page cursors are generated run time and only valid until the first page is refreshed again to get a new cursor. Following this approach, We notice that all the pages that were previously fetched will never be deleted after re-fetching the first page and hence get accumulated as the user fetches more pages and re-fetches leading to larger cache size over time. Not to mention the more number of records, the higher the read time.
2. Cannot watch updates to items from the second page onwards:
We want to set up a GraphQLQueryWatcher on the paginated query, such that any changes to the items, including items from all the pages retrieved so far. However, Looking at the implementation of the GraphQLQueryWatcher, it appears that with this approach, Watcher will notify only for the items returned from the first page since dependent keys for the watcher includes only keys from the first page.
Approach 2: Manually merge data from subsequent pages into the first page
In order to solve the Approach #1 Issue #2, We took inspiration from Apollo react Pagination which does the following:
fetchIgnoringCacheCompletely
cache policy and manually write the data into the First-page query.Issues with Approach 2
1. Writes are slow
As we can notice in Step #2, we merge the previous page with data pulled from the next page and re-write the entire data back. As we fetch more pages, the write latency increases.
2 Latency of reading the first page exponentially increases
Since we merge data from all pages into the first page, reading the first page exponentially increases based on the number of items present in the cache. This is more evident with queries that have an increasing number of attributes that are non-scalar data types in the query as the batch loader does round trip to the database for each attribute. With our sample of data, the read time for a query with medium complex schema has clocked 10 seconds to read 150 items on an iPhone XS device.
The text was updated successfully, but these errors were encountered: