apollo-client
apollo-client copied to clipboard
Processing large data set extremely slow
We are using @apollo/client with apollo-link-rest in a react native application. When querying an endpoint of ours which supplies a fairly large response (4.4mb) using apollo, we are getting a response time from the api in about 2 seconds however the parsed data isn't available from apollo for about 30-180 seconds.
The request is as follows, I cannot share the data although we are returning about 1300 organizations and 4000 products. They each have around 5-10 keys of short strings.
@rest(
type: "redacted",
path: "redacted",
) {
organizations @type(name: "Organization") {
...FULL_ORGANIZATION_FRAGMENT
}
products @type(name: "Product") {
...FULL_PRODUCT_FRAGMENT
}
}
Whilst debugging I have built a raw request workaround using fetch that fetches the data, adds the __typenames via looping all organizations and products and writes the data to cache. This process is resolving in around 3-4 seconds including the request.
I understand that apollo is doing much more than my raw request, although i'm sure you'll agree that 30-180 seconds more is quite a big difference. Why is apollo taking such a vast amount of time more to process this data and is there anything we can do to prevent this?
System: OS: macOS 11.3.1 Binaries: Node: 16.5.0 - ~/.nvm/versions/node/v16.5.0/bin/node Yarn: 1.22.11 - ~/.nvm/versions/node/v16.5.0/bin/yarn npm: 7.19.1 - ~/.nvm/versions/node/v16.5.0/bin/npm Browsers: Chrome: 92.0.4515.159 Safari: 14.1 npmPackages: @apollo/client: ^3.4.5 => 3.4.5 apollo-link-rest: ^0.8.0-beta.0 => 0.8.0-beta.0 apollo-type-patcher: ^1.0.3 => 1.0.3 apollo3-cache-persist: ^0.11.0 => 0.11.0
@piers-smartwyre Are these numbers from React Native Android specifically? How does the iOS simulator/device compare?
@benjamn Sorry, those numbers are from iOS simulator. Although I am experiencing similar and sometimes worse numbers on an iOS build.
The React Native JS environment is typically 30x-50x slower than a desktop browser, especially the Android version. That unfortunate reality means you may be forced to paginate your data, ideally fetching just enough in the initial payload to fill the visible screen.
Still, I agree 30-180 seconds seems like a pathologically large (and variable!) amount of additional time. A few thoughts:
- Double-check
ApolloClientthinks it's running in production rather than development, at least when you're doing benchmarks. You canimport { DEV } from "@apollo/client/utilities"and check/log thatDEVisfalse. The React Native__DEV__constant should be determining this for you, but it's good to make sure. - Try the same query with
fetchPolicy: "no-cache"to get a sense for how much of the time is attributable to trying to store the data in the cache. I don't recommend this policy in general, but it's a useful diagnostic. - Try different counts of organizations/products, and plot them on a graph. The relationship should be linear-ish.
- 180 seconds / (1300 orgs + 4000 products) = ~34ms per org/product
- Find a way to take a heap snapshot, or otherwise inspect memory usage. Running out of memory can cause garbage collection to take a substantial fraction of JS execution time.
@benjamn Here is a quick react native repo i've put together with an express server returning a sample payload. If you spin that up you'll be able to see the drastic difference i'm experiencing.
https://github.com/piers-smartwyre/ApolloPerformanceTest
Thanks for the advice, i'll look into those and do some profiling.
I've recently done some testing with React Native, and the speeds were comparable to a normal Desktop at this point.
So it seems like React Native has caught up here - as a result, I'm going to close this issue.
If this is still a concern, please leave a comment here.
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. For general questions, we recommend using StackOverflow or our discord server.